Vue: 2.0 Changes

Created on 14 May 2016  ·  210Comments  ·  Source: vuejs/vue

This is a live document. Last update: 08/17/2016 as of 2.0.0-rc.2

General Notes

  • A checked item means it has been implemented in the 2.0 development branch.
  • Features subject to change during development.
  • The breaking change list is not guaranteed to be complete during development.
  • There are some upgrade tips at the end.

    High Level Changes

  • The template parser no longer relies on the DOM (unless you are using the real DOM as your template), so as long as you are using string templates (<script type="text/x-template">, inline JavaScript strings, or compiled via single-file components), you are no longer subject to any of the template parsing limitations in 1.x. However, if you are relying on mounting to an element with existing content as template (using the el option), you will still be subject to those limitations.

  • The compiler (the part which converts a template string to a render function) and the runtime can now be separated. There will be two different builds:

    • Standalone build: includes both the compiler and the runtime. This functions basically exactly the same Vue 1.x does.
    • Runtime only build: since it doesn't include the compiler, you need to either pre-compiled templates in a compile step, or manually written render functions. The npm package will export this build by default, since when consuming Vue from npm, you will likely be using a compilation step (with Browserify or Webpack), during which vueify or vue-loader will perform the template pre-compilation.

      Global config

  • [x] Vue.config.silent

  • [x] Vue.config.optionMergeStrategies
  • [x] Vue.config.devtools
  • [x] Vue.config.errorHandler new - global hook for handling uncaught errors during component render and watchers (default behavior is logging the error stack throwing in place)
  • [x] Vue.config.keyCodes new - configure custom key aliases for v-on.
  • Vue.config.debug deprecated, no longer useful since warnings come with stack traces by default now
  • Vue.config.async deprecated, async is required for rendering performance
  • Vue.config.delimiters reworked as a component-level option
  • Vue.config.unsafeDelimiters deprecated, use v-html

    Global API

  • [x] Vue.extend

  • [x] Vue.nextTick
  • [x] Vue.set
  • [x] Vue.delete
  • [x] Vue.directive
  • [x] Vue.component
  • [x] Vue.use
  • [x] Vue.mixin
  • [x] Vue.compile new (only in standalone build)
  • [x] Vue.transition

    • stagger deprecated, set and access data-index on el instead

  • [x] Vue.filter
  • Vue.elementDirective deprecated, just use components
  • Vue.partial deprecated, use functional components

    Options

data
  • [x] data
  • [x] props

    • [x] prop validation

    • [x] default value

    • coerce deprecated. If you want to convert a prop, setup a local computed value based on it.

    • prop binding modes deprecated (v-model can work on components)

  • [x] propsData new, instantiation only
  • [x] computed
  • [x] methods
  • [x] watch

    DOM
  • [x] el

  • [x] template
  • [x] render new
  • replace deprecated, components now must have exactly one root element.

    Lifecycle Hooks
  • [x] init beforeCreate

  • [x] created
  • [x] beforeDestroy
  • [x] destroyed
  • [x] beforeMount new
  • [x] mounted new
  • [x] beforeUpdate new
  • [x] updated new
  • [x] activated new (for keep-alive)
  • [x] deactivated new (for keep-alive)
  • [x] ready deprecated, use mounted (there's no longer the guarantee to be in-document)
  • activate deprecated, moved into vue-router
  • beforeCompile deprecated, use created
  • compiled deprecated, use mounted
  • attached deprecated, use custom in-dom check in other hooks
  • detached deprecated, same as above

    Assets
  • [x] directives

  • [x] components
  • [x] transitions
  • [x] filters
  • partials deprecated
  • elementDirectives deprecated

    Misc
  • [x] parent

  • [x] mixins
  • [x] name
  • [x] extends
  • [x] delimiters new, replacing the original global config option. Only available in standalone build.
  • [x] functional new, makes the component stateless and instance-less (just a render function that returns virtual nodes)
  • events deprecated, since no more event propagation

    Instance Properties

  • [x] vm.$data

  • [x] vm.$el
  • [x] vm.$options
  • [x] vm.$parent
  • [x] vm.$root
  • [x] vm.$children
  • [x] vm.$refs
  • vm.$els deprecated, merged with $refs

    Instance Methods

data
  • [x] vm.$watch
  • vm.$get deprecated, just retrieve values directly
  • vm.$set deprecated, use Vue.set
  • vm.$delete deprecated, use Vue.delete
  • vm.$eval deprecated, no real use
  • vm.$interpolate deprecated, no real use
  • vm.$log deprecated, use devtools

    events
  • [x] vm.$on

  • [x] vm.$once
  • [x] vm.$off
  • [x] vm.$emit
  • vm.$dispatch deprecated, use global event bus or Vuex. (see below)
  • vm.$broadcast deprecated, same as above

    DOM
  • [x] vm.$nextTick

  • vm.$appendTo deprecated, just use native DOM API on vm.$el.
  • vm.$before deprecated
  • vm.$after deprecated
  • vm.$remove deprecated

    Lifecycle
  • [x] vm.$mount

  • [x] vm.$destroy

    Directives

  • [x] v-text

  • [x] v-html but {{{ }}} shorthand has been deprecated
  • [x] v-if
  • [x] v-show
  • [x] v-else
  • [x] v-for

    • [x] key (replacing track-by)

    • [x] Object v-for

    • [x] range v-for

    • [x] argument order updates: (value, index) in arr, (value, key, index) in obj

    • $index and $key deprecated

  • [x] v-on

    • [x] modifiers

    • [x] on child component

    • [x] custom keyCodes (now avaiable via Vue.config.keyCodes instead of Vue.directive('on').keyCodes)

  • [x] v-bind

    • [x] as prop

    • [x] xlink

    • [x] bind object

  • [x] v-bind:style

    • [x] prefix sniffing

  • [x] v-bind:class
  • [x] v-model

    • [x] lazy (as modifier)

    • [x] number (as modifier)

    • [x] ignoring composition events

    • debounce deprecated, use v-on:input + 3rd party debounce function

  • [x] v-cloak
  • [x] v-pre
  • [x] v-once new
  • v-ref now just a special attribute as ref
  • v-el deprecated (merged with ref)

    Special Components

  • [x] <component>

    • [x] :is
    • [x] async components
    • [x] inline-template
  • [x] <transition>
  • [x] <transition-group>
  • [x] <keep-alive>
  • [x] <slot>
  • partial deprecated

    Special Attributes

  • [x] key

  • [x] ref
  • [x] slot

    Server-side Rendering

  • [x] renderToString

  • [x] renderToStream
  • [x] client-side hydration

    Other Breaking Changes

v-for iteration syntax change

  • Deprecating $index and $key

    Both of these are being deprecated in favor of more explicit named indices and keys. This syntax is a bit magical and has limitations in nested loops. As a bonus, there will be two fewer points of syntax for newcomers to learn.

  • New array syntax

    • value in arr

    • (value, index) in arr (switched order of arguments to be more consistent with JavaScript's forEach and map)

  • New object syntax

    • value in obj

    • (value, key) in obj (switched order of arguments, partly to be more consistent with many common object iterators, such as lodash's)

    • (value, key, index) in obj (index will now be available in object iteration for visual purposes, such as table striping)

      Directive interface change


In general, in 2.0 directives have a greatly reduced scope of responsibility: they are now only used for applying low-level direct DOM manipulations. In most cases, you should prefer using Components as the main code-reuse abstraction.

Directives no longer have instances - this means there's no more this inside directive hooks and bind, update and unbind now receives everything as arguments.

Note the binding object is immutable, setting binding.value will have no effect, and properties added to it will not be persisted. You can persist directive state on el if you absolutely need to:

<div v-example:arg.modifier="a.b"></div>
// example directive
export default {
  bind (el, binding, vnode) {
    // the binding object exposes value, oldValue, expression, arg and modifiers.
    binding.expression // "a.b"
    binding.arg // "arg"
    binding.modifiers // { modifier: true }
    // the context Vue instance can be accessed as vnode.context.
  },

  // update has a few changes, see below
  update (el, binding, vnode, oldVnode) { ... },

  // componentUpdated is a new hook that is called AFTER the entire component
  // has completed the current update cycle. This means all the DOM would
  // be in updated state when this hook is called. Also, this hook is always
  // called regardless of whether this directive's value has changed or not.
  componentUpdated (el, binding, vnode, oldVNode) { ... },

  unbind (el, binding, vnode) { ... }
}

You can use destructuring if you only care about the value:

export default {
  bind (el, { value }) {
    // ...
  }
}

In addition, the update hook has a few changes:

  1. It no longer gets called automatically after bind.
  2. It now always gets calls when the component is re-rendered, regardless of whether the value it's bound to has changed or not. You can compare binding.value === binding.oldValue to skip unnecessary updates, but there are also cases where you'd want to always apply updates, e.g. when the directive is bound to an Object that might have been mutated instead of replaced.

elementDirective, directive params and directive options such as acceptStatement, deep etc. are all deprecated.

Filter Usage and Syntax Change

In Vue 2.0, there are several changes to the filter system:

  1. Filters can now only be used inside text interpolations ({{}} tags). In the past we've found using filters with directives such as v-model, v-on etc. led to more complexity than convenience, and for list filtering on v-for it is more appropriate to move that logic into JavaScript as computed properties.
  2. Vue 2.0 will not ship with any built-in filters. It is recommended to use standalone libraries dedicated for solving problems in a specific domain, e.g. moment.js for formatting dates and accounting.js for formatting financial currencies. You are also welcome to create your own filter pack and share it with the community!
  3. The filter syntax has changed to be more inline with JavaScript function invocation, instead of taking space-delimited arguments:

{{ date | formatDate('YY-MM-DD') }}

Transition System

Transition CSS class changes:

The always-on v-transition class is no longer added and Vue now uses the same classes Angular and React CSSTransitionGroup does:

  • v-enter: applied before element is inserted, remove after 1 tick. (starting state for enter)
  • v-enter-active: applied before element is inserted, removed when transition/animation finishes. (active + ending state for enter)
  • v-leave: applied right when the leave transition is triggered, remove after 1 tick (starting state for leave)
  • v-leave-active: applied right when the leave transition is triggered, removed when the transition/animation finishes. (active + ending state for leave)

v-enter-active and v-leave-active gives you the ability to specify different easing curves for enter/leave transitions. In most cases, upgrading means simply replacing your current v-leavewith v-leave-active. (For CSS animations, use v-enter-active + v-leave-active)

Transition API Change

  • The <transition> component

    All single-element transition effects are now applied by wrapping the target element/component with the <transition> built-in component. This is an abstract component, which means it does not render an extra DOM element, nor does it show up in the inspected component hierarchy. It simply applies the transition behavior to the wrapped content inside.

    The simplest usage example:

    <transition>
    <div v-if="ok">toggled content</div>
    </transition>
    

    The component defines a number of props and events that maps directly to the old transition definition options:

    Props

    • name: String

    Used to automatically generate transition CSS class names. e.g. name: 'fade' will auto expand to .fade-enter, .fade-enter-active, etc. Defaults to "v".

    • appear: Boolean

    Whether to apply transition on initial render. Defaults to false.

    • css: Boolean

    Whether to apply CSS transition classes. Defaults to true. If set to false, will only trigger JavaScript hooks registered via component events.

    • type: String

    Specify the type of transition events to wait for to determine transition end timing. Available values are "transition" and "animation". By default, it will automatically detect the type that has a longer duration.

    • mode: String

    Controls the timing sequence of leaving/entering transitions. Available modes are "out-in" and "in-out"; defaults to simultaneous.

    • enterClass, leaveClass, enterActiveClass, leaveActiveClass, appearClass, appearActiveClass: String

    Individually configure transition CSS classes.

    Example applying transition to dynamic components:

    <transition name="fade" mode="out-in" appear>
    <component :is="view"></component>
    </transition>
    

    Events

    Corresponds to the JavaScript hooks available in 1.x API.

    • before-enter
    • enter
    • after-enter
    • before-leave
    • leave
    • after-leave
    • before-appear
    • appear
    • after-appear

    Example:

    <transition @after-enter="transitionComplete">
    <div v-show="ok">toggled content</div>
    </transition>
    

    When the entering transition completes, the component's transitionComplete method will be called with the transitioned DOM element as the argument.

    Some notes:

    • leave-cancelled is no longer available for insertion/removals. Once a leave transition starts, it cannot be cancelled. It is, however, still available for v-show transitions.
    • Similar to 1.0, for enter and leave hooks, the presence of cb as the second argument indicates the user wants explicit control of the ending timing of the transition.
  • The <transition-group> component

    All multi-element transition effects are now applied by wrapping the elements with the <transition-group> built-in component. It exposes the same props and events as <transition> does. The difference being that:

    1. Unlike <transition>, <transition-group> renders a real DOM element. By default it renders a <span>, and you can configure what element is should render via the tag prop. You can also use it with the is attribute, e.g. <ul is="transition-group">.
    2. <transition-group> does not support the mode prop.
    3. Every child in a <transition-group> must be uniquely keyed.

    Example:

    <transition-group tag="ul" name="slide">
    <li v-for="item in items" :key="item.id">
      {{ item.text }}
    </li>
    </transition-group>
    

    Moving Transitions

    <transition-group> supports moving transitions via CSS transform. When a child's position on screen has changed after an updated, it will get applied a moving CSS class (auto generated from the name prop or configured with the moveClass prop). If the CSS transform property is "transition-able" when the moving class is applied, the element will be smoothly animated to its destination using the FLIP technique.

    See a live demo here.

  • Creating Reusable Transitions

    Now that transitions are applied via components, they are no longer considered an asset type, so the global Vue.transition() method and the transition option are both deprecated. You can just configure the transition inline with component props and events. But how do we create reusable transition effects now, especially those with custom JavaScript hooks? Well, the answer is creating your own transition components (they are particularly suitable as functional components):

    Vue.component('fade', {
    functional: true,
    render (createElement, { children }) {
      const data = {
        props: {
          name: 'fade'
        },
        on: {
          beforeEnter () { /* ... */ }, // <-- Note hooks use camelCase in JavaScript (same as 1.x)
          afterEnter () { /* ... */ }
        }
      }
      return createElement('transition', data, children)
    }
    })
    

    You can then use it like this:

    <fade>
    <div v-if="ok">toggled content</div>
    </fade>
    

    v-model changes

  • The lazy and number params are now modifiers:

    <input v-model.lazy="text">
    
  • New modifier: .trim - trims the input, as the name suggests.
  • The debounce param has been deprecated. (See upgrade tip at bottom)
  • v-model no longer cares about initial inline value. It will always treat the Vue instance data as the source of truth. This means the following will render with a value of 1 instead of 2:

    data: {
    val: 1
    }
    
    <input v-model="val" value="2">
    

    Same goes for <textarea> with existing content. So instead of:

    <textarea v-model="val">hello world</textarea>
    

    Do:

    data () {
    return {
      val: 'hello world'
    }
    }
    
    <textarea v-model="val"></textarea>
    

    The main idea is that the JS side should be considered the source of truth, not your templates.

  • v-model no longer works when used on a v-for iterated primitive value:

    <input v-for="str in strings" v-model="str">
    

    This doesn't work because it's the equivalent of this in JavaScript:

    strings.map(function (str) {
    return createElement('input', ...)
    })
    

    As you can see, setting str to another value in the iterator function will do nothing because it's just a local variable in the function scope. Instead, you should use an array of objects so that v-model can update the field on the object:

    <input v-for="obj in objects" v-model="obj.str">
    

    Props Behavior

  • .once and .sync are deprecated. Props are now always one-way down. To produce side effects in the parent scope, a component needs to explicitly emit an event instead of relying on implicit binding.

  • Mutating a prop locally is now considered an anti-pattern, e.g. declaring a prop a and then set this.a = someOtherValue in the component. Due to the new rendering mechanism, whenever the parent component re-renders, the child component's local changes will be overwritten. In general, in 2.0 you should treat props as immutable. Most use cases of mutating a prop can be replaced by either a data property or a computed property.

    keep-alive

keep-alive is no longer a special attribute: it is now a wrapper component, similar to <transition>:

  <keep-alive>
    <component :is="view"></component>
  </keep-alive>

This makes it possible to use keep-alive on multiple conditional children (note the children should eventually evaluate to a single child - any child other than the first one will be ignored):

  <keep-alive>
    <comp-a v-if="a > 1"></comp-a>
    <comp-b v-else></comp-b>
  </keep-alive>

When used together with <transition>, make sure to nest it inside:

  <transition>
    <keep-alive>
      <component :is="view"></component>
    </keep-alive>
  </transition>

Slots

  • It is no longer supported to have duplicate <slot>s with the same name in the same template. When a slot is rendered it is "used up" and cannot be rendered elsewhere in the same render tree.
  • Content inserted via named <slot> no longer preserves the slot attribute. Use a wrapper element to style them, or, for advanced use cases, modify the inserted content programmatically using render functions.

    Refs

  • v-ref is now no longer a directive: it is now a special attribute similar to key and transition:

    <!-- before -->
    <comp v-ref:foo></comp>
    
    <!-- after -->
    <comp ref="foo"></comp>
    

    Dynamic ref bindings are now also supported:

    <comp :ref="dynamicRef"></comp>
    
  • vm.$els and vm.$refs are merged. When used on a normal element the ref will be the DOM element, and when used on a component the ref will be the component instance.
  • vm.$refs are no longer reactive, because they are registered/updated during the render process itself. Making them reactive would require duplicate renders for every change.

    On the other hand, $refs are designed primarily for programmatic access in JavaScript - it is not recommended to rely on $refs in templates because it entails referring to state that does not belong to the instance itself.

    Misc

  • track-by has been replaced with key. It now follows the same rule for binding an attribute: without v-bind: or : prefix, it is treated as a literal string. In most cases you'd want to use a dynamic binding, which expects a full expression instead of a string key. For example:

    <!-- 1.x -->
    <div v-for="item in items" track-by="id">
    
    <!-- 2.0 -->
    <div v-for="item in items" :key="item.id">
    
  • Interpolation inside attributes are deprecated:

    <!-- 1.x -->
    <div id="{{ id }}">
    
    <!-- 2.0 -->
    <div :id="id">
    
  • Attribute binding behavior change: only null, undefined and false are considered falsy when binding attributes. This means 0 and empty strings will render as-is. For enumerated attributes. This means :draggable="''" will render as draggable="true".

    Also, for enumerated attributes, in addition to the falsy values above, the string value of "false" will also render as attr="false".

  • When used on a custom component, v-on now only listens to custom events $emitted by that component. (no longer listens to DOM events)
  • v-else no longer works with v-show - just use negation expression.
  • One time bindings ({{* foo }}) deprecated - use v-once instead.
  • Array.prototype.$set/$remove deprecated (use Vue.set or Array.prototype.splice instead)
  • :style no longer supports inline !important
  • root instance can no longer use template props (use propsData instead)
  • The el option can no longer be used in Vue.extend. It can now only be used as an instance creation option.
  • Vue.set and Vue.delete cannot work on Vue instances. It is now mandatory to properly declare all top-level reactive properties in the data option.
  • It is now also prohibited to replace a component instance's root $data. This prevents some edge cases in the reactivity system and makes the component state more predictable (especially with type-checking systems).
  • User watchers created via vm.$watch are now fired before the associated component re-renders. This gives the user a chance to further update other state before the component re-render, thus avoiding unnecessary updates. For example, you can watch a component prop and update the component's own data when the prop changes.

    To do something with the DOM after component updates, just use the updated lifecycle hook.

    Upgrade Tips

How to Deal with Deprecation of $dispatch and $broadcast?

The reason that we are deprecating $dispatch and $broadcast is that event flows that depend on the components tree structure can be hard to reason about when the components tree becomes large (simply put: it doesn't scale well in large apps and we don't want to set you up for pain later). $dispatch and $broadcast also do not solve the communication between sibling components. Instead, you can use a pattern similar to the EventEmitter in Node.js: a centralized event hub that allows components to communicate, no matter where they are in the components tree. Because Vue instances implement the event emitter interface, you can actually use an empty Vue instance for that purpose:

var bus = new Vue()
// in component A's method
bus.$emit('id-selected', 1)
// in component B's created hook
bus.$on('id-selected', this.someMethod)

And don't forget to use $off to unbind the event.

// in component B's destroyed hook
bus.$off('id-selected', this.someMethod)

This pattern can serve as a replacement for $dispatch and $broadcast in simple scenarios. But for more complex cases, it is recommended to introduce a dedicated state management layer using Vuex.

How to Deal with the Deprecation of Array Filters?

For list filtering with v-for - one of the more common usage of filters - it is now recommended to use computed properties that return a processed copy of the original Array (see updated data grid example). The benefits is that you are no longer limited by the arbitrary filter syntax/API - it's just plain JavaScript now, and you naturally have access to the filtered result because it is a computed property.

Also see this discussion thread.

How to Deal with the Deprecation of debounce for v-model?

Debouncing is used to limit how often we execute Ajax requests and other expensive operations. Vue's debounce attribute parameter for v-model makes this easy, but it also debounces _state updates_ rather than the expensive operations themselves, which comes with limitations.

These limitations become apparent when designing a search indicator. Take a look at that example. Using the debounce attribute, there'd be no way to detect a dirty input before the search begins, because we'd lose access to the input's real-time state. By decoupling the debounce function from Vue, we're able to debounce _only_ the operation we want to limit.

There will be other times when debouncing isn't _quite_ the right wrapper function. In the very common example of hitting an API for search suggestions, waiting to offer suggestions until after the user has stopped typing isn't an ideal experience. What you probably want instead is a throttling function. Now since you're already using a utility library like lodash for debounce, refactoring to use throttle instead takes only a few seconds!

Most helpful comment

@chrisvfritz @Uninen correction: Vuex 2.0 also works for Vue 1.x.

Next major version of vue-router will only support Vue 2.x.

All 210 comments

I just saw that certain features will only be available in the standalone build. Does that mean that this and the NPM version are significantly different?

@rekateka 2.0 standalone build means (compiler + runtime). The default export of the NPM package will be runtime only, because if installing from NPM, you will likely pre-compile the templates with a build tool.

Thanks, @yyx990803. I still have a couple more questions regarding the compiler and other features, but I've used the forum for that.

Are there any worrisome changes made to docs I should review by any chance? Great work! Keep it up man. You're redefining web development. Thank you!

Can I get this.arg of my directive?

I see vnode.data.directives has arg, but when I have two or more directives, I can not know the index.

<!-- show @ 0, img @ 1-->
<img v-show="true" v-img:200*200="imgSrc">
<!-- img @ 0, show @ 1-->
<img v-img:200*200="imgSrc" v-show="true">

Should I use forEach? Thank you!

@banricho good point, that's been overlooked! See updated directive function signature.

First of all, sorry for I am not quite sure that could I ask this problem here, and I have a little bit requirements want to say.
The requirement is I hope I can design my component's usage like this

<carousel>
  <img src="..." alt="..." desc="..." is="argument">
  <img src="..." alt="..." desc="..." is="argument">
</carousel>

I hope the children can be as some kind of arguments, not only limit in attributes
For now I can make a component, the usage like

<carousel items="[{}, {}, {}]"></carousel>

But I think it's not quite good, I hope it can like this one I made before in React coverflow

@andyyou - that question is probably best posted on the forum, since it isn't an issue, nor a clear suggestion, nor any real help to this issue.

http://forum.vuejs.org/

If you find out that your requirements can't be met with Vue in your forum thread, then you can open a new issue here.

Scott

@smolinari Thanks

"But for more complex cases, it is recommended to introduce a dedicated state management layer using Vuex." This seems to imply that state should be used over events. I see them as completely separate - an event is a moment in time, whereas state does not change. You could say that you could watch the state, but that also does not convey a specific moment, but instead anytime something changes. I'm interested in the meaning behind this recommendation.

@jrenton Generally, we can consider the event system simply as component A telling component B to change it's state, or A telling B to do something else.
So for the first case, we can use state management (managing a shared state for A and B) instead of using event system to let A tell B to change state.
For the second case, I think it can be handled with the 'event bus' approach pretty well.

@jrenton instead of a soup of components talking to each other Vuex suggest a single channel for components to express "intentions" with actions, and record "facts" with mutations.

I'm using Twig along with Vue.

Until now (vue 1.0) I've been passing data into my components like this:

<my-component data="{{ DATA }}"><my-component>

(Note that {{ and }} are twig tags - for vue I've been using custom delimiters ${ and })

If I'm understanding things correctly, in Vue 2.0 I should do it like this:

<my-component :data=" '{{ DATA }}' "></my-component>
right?

@gholol no it's just

<my-component :data="{{ DATA }}"></my-component>

Actually it seems your old usage shouldn't work in the first place.

Well it worked fine...

Like I said, the data are coming from twig templating engine. Now in Vue 2.0 it doesn't work. I've been trying to pass it like you said (without single apostrophes) but data property gets undefined.

Error: SyntaxError: missing } after property list

EDIT: It works, I forgot to mention that the DATA variable is a string

@jrenton My idea and motivation is quite simple seems Vue doesn't like React that compel us to use JSX. We can choose a lot of template.

I hope I can use children element syntax as a parameter(arguments) pass args to parent because in some template language like slim if you have a bit many attributes or say the attr's name is quite long then we have to put all the things in one line. it's easier make code of one line over 80 characters.

@yyx990803 Feeling adventurous today wanted to see how much effort would it take to migrate some 1.0 to 2.0a, unfortunately since it's not possible to use simple interpolation anymore, how would I go about and do something simple as <input type="text" name="account[categories][{{ category.id }}]"> in 2.0?

ES6 inline templates work in binding expressions:

<input type="text" :name="`account[categories][${ category.id }]`">

https://jsfiddle.net/Linusborg/cm4v75xh/

If that's the only way to get this working on 2.0, then don't mind me saying that that's a regression in the lovely syntax 1.0 got us used to – yes I know that's just ES2015.

I assume interpolation was removed for performance reasons? I just hope it's worth the uglier syntax.

@oskarkrawczyk I assume you want to end up with something like name="account[categories][fruits]" in your DOM, because this is what your expression would render.

The 2.0 version (and proper 1.0, in fact) will be :name=" 'account[categories][' + category.id + ']' ".

@simplesmiler Understood. I think {{ }} just spoiled me a bit.

@yyx990803 can I dynamically insert component, like this?

    render () {
        return this.$createElement('div', { staticClass: 'list-container' }, this.list)
    },
    data () {
         return {
               list: []
         }
    },
    method: {
         a () {
               this.list.push(this.$createElement('myComponent', {}))    
         }
    }

How I can bind few values for an attribute which depend on expression? For example:

new Vue({
  el:'body',
  data:{
    flag: true
  }
})
<input type="text" v-bind:placeholder="{test: flag, test2: !flag}" />

I expect next result:

<input type="text" placeholder="test" />
<!-- or -->
<input type="text" placeholder="test2" />

@nervgh this is not the right place to ask this question.
Use ternary expression, v-bind:placeholder="flag ? 'test' : 'test2'".

@simplesmiler , thanks for your answer. I try to say that _Object-Syntax_ will be useful in these cases, but is does not work as I expect.

@nervgh object syntax is only applicable to attributes that take a list of strings. Of native attributes the only such attribute is class, and for the components there would be no way to detect from the child side whether you meant to send a list of strings or a proper object.

Re: .once and .sync are deprecated.

Doesn't this break really common design patterns?

I can't think how you'd be able to have simple components for handling form fields without these.

I have simple components for different form field types, eg here's my "textbox" component template::

<label>{{type.caption}}:<input type="text" v-model="data"></label>

...and also a more complex component for lists which provides a ui to add and remove elements from arrays in the data structure

Then I use these components eg like so:

<div v-for="field in type.fields">
    <component :data.sync="data[field.name]" :is="field.ctype" :type="field">

Note: All of these components have two props: data and type. data is the node in the data structure being edited that the component is responsible for providend a UI for editing, and type is the node in the (massive, static) data structure which contains the types/fields hierarchy.

How can stuff like that work without .sync?

It seems to me that it would severely complicate things to create some sort of messaging system between these components where the sub-components can somehow communicate to the parent which sub-component they are, and the parent can then figure out what part of its data structure to modify.

I really hope I'm missing something.... because it looks like you're saying that using components to create editors for parts of your data structure is an anti-pattern. Whaat? So far that's the only thing I've used Vue for. I'm guessing you think that removing this feature will encourage people to write cleaner code. Maybe it will have that effect on some people, but many people will write much nastier code to work around this limitation. Modifying state is the only useful thing that computers do. Please continue to make this easier.

@JasonWoof v-model in 2.0 can work on custom components. The component simply needs to:

  1. expose a prop named value
  2. emit an input event when the value needs to be synced to parent, e.g. this.$emit('input', value)

See example.

@yyx990803 Thanks for the explanation and link. Now I'm just stuck on:

Why remove .sync?

I don't see the advantage, only disadvantages. The example you linked shows that you can achieve the same thing with either :selected.sync or v-model. I only see disadvantages for the v-model method:

  1. It requires significant boiler-plate on the sub-component side, is more complicated, more to learn, etc.
  2. You can only pass one value with v-model, but you can have multiple .sync props

I don't see how switching to v-model makes anything clearer/cleaner. In both cases, the only indication in the parent that the child component can easily modify parent state is the syntax of the prop in the template. I would even argue that .sync is more clear.

The other thing is that when you pass objects/arrays/etc as props, then they are mutable from the child component. So you can't shield programmers from being able to change the state from the child components in this case (which I assume is very common.) So it seems to me like you are introducing a stumbling block by removing the thing that makes it so passing string values works the same as passing object values. .sync makes my code simpler and more consistent by always having my "data" props writable from the child side, no matter the data type.

I'm new to Vue.js (3 days ago) but from what I can see so far, Vue.js is valuable mainly because of two things:

  1. easy dom manipulation with templates
  2. automatic value/data change propagation, including triggering template changes

At least that's what I've discovered so far.

It seems to me that removing .sync makes it difficult to get Vue.js to consistently do the second.

@JasonWoof because explicit vs. implicit side effects outside of the components own scope makes all the difference in long term maintainability.

... and while one could argue that people simply should learn when to not use .sync, our experience so far is different. people tend to rely too much on this and create code they later can hardly debug.

so this is a design decision to force people to do it right from the beginning.

an example:

  • We sync a value name between a parent and a child. all is well.
  • we decide _'hey, when that value changes, we need to do something in the parent!'_
  • So, we create a watchfunction. Nice!
  • Later on we realize that the watcher seems to fire when we don't want it to. But we can't really tell why, because we can't really put console.log() anywhere to trace the behaviour.
  • After much hard thinking, we realize that we _really_ only want that _something_ to happen when the value is changed in the parent, not the child or the "grandparent".
  • Now we try to find a way to differenciate these scenarios in the watch function somehow.
  • Only to realize that this makes a simple thing very complicated
  • and in the end, someone tells us to remove sync, so we throw it all away and use a one-way prop and an emitted event to handle the situation - the code becomes simpler and more explicit, so it's simple to reason about how and when data flows and it becomes easier to debug it. The bug is found quickly and we can move on.

...and this becomes even more crazy when you sync more than one level deep.

This is an (anti-)pattern we have seen over and over on the forums and in the gitter chat.

Removing .sync forces people to write clear, explizit, maintainable code from the start, because their code won't stay simple enough for .sync for very long, most of the time.

OK. Thank you for explaining.

It's good to hear what problem you are trying to solve.

I seriously doubt this will help though... Make it so people can't easily break the patters you like and people will do far worse things to work around the limitations.

This reminds me a lot of abstraction. Abstractions get us into so much trouble. They make code hard to read, hard to debug, etc.... But you can't fix this by taking away the ability to make abstractions... that's pretty much the thing that makes programming possible/useful. The solution to this is not at the language or framework level, but in teaching, advice, learning. We encourage people not to make things overly abstract.

It sounds to me like you are talking about such a design philosophy. In many cases, it's a great philosophy to keep in mind while coding. But when it is imposed as a limitation, and the programmer thinks that this limitation stops her from doing what she needs to do, then she's going to work around it, which will result in all the problems you were trying to avoid and worse.

People are not going to stop trying to mutate parent state from the children. You can't force people not to do that.

Your v-model thing is complicated enough that I would work around this problem by passing the parent object/array and a key so that the child can modify it.

I guess this last bit hit's at the heart of what I'm trying to get across: I (personally) see the lack of .sync as a problem, and will work around it or not use your framework. I bet a lot of people will have the same approach.

Perhaps this goes without saying, but it makes me a little angry when people try to impose design philosophies on me. I would much rather build things that go terribly wrong and learn not to do that again than to use systems that purposely withhold power for fear that I might use it badly.

P.S. Sorry, I can't help myself, one more comment, then I'll leave you guys alone. Most programmers write code that they cannot debug. This happens to every programmer in every language with every framework. This is how programmers become better programmers: they make mistakes, they make code they cannot fix, they learn how to write things differently in the future. Please don't dumb down your framework for everybody in an attempt to make it so programmers who abstract themselves into the corner can make their stuff a little bit more confusing/complex before it becomes such a mess that they can't debug it.

@JasonWoof it has nothing to do with "dumbing down", and preventing users from common pitfalls / ensuring better maintainability is by definition part of the job of a framework. We made the decision based on first hand experience designing, using the framwork itself, and observing user behavior in various use cases. If it's an anti-pattern, we will discorage users from using it, and provide guidence on the idiomatic solution. You are free to disagree with that based on your personal opninion, but I find your arguments hardly convincing.

People are not going to stop trying to mutate parent state from the children. You can't force people not to do that.

Sure. And we _won't_ 'force' them, because there may be some edge cases where this might still be nessessary. So you can still access this.$parent, you can pass $data through a prop etc, but quite frankly doing so will be not much more convient that $emiting an event most of the time, so they won't be as attractive as .sync sugar.

Also, $parent et.al. are not part of the official guide, so users who use them are actively working around suggested best practices - which they are free to do, but we don't encourage that behaviour.

Consequently, the framework should not encourage similar behaviour by providing 'magical' syntactic sugar like .sync if we feel that such a feature is misused in most scenarios and opposed to the best practices the framework seeks to establish.

尤大 有没有中文版的。。

What does the compatibility look like for vue-router?

@roblav96

There are some changes needed to be compatible, we are hoping to better incorporate the Router into Vue.

@blake-newman

Can we get a boilerplate template together on vue-cli? I can't seem to get any of this working 😢

@roblav96

There are some currently, there are some change changes needed with vue-loader to make it compatible. Currently 2.0 should be used for experimentation only until all further dependencies for large scale applications are updated.

Is there an ETA for the beta / release candidates?

@Evertt Alpha is due this week. Beta will follow with documentation completed, and maybe more support from core extending libraries (Vue-router ect). Release Candidate when Beta is proven successful.

@blake-newman thank you for that quick, concise and complete response. Those are the best. :-D

Any workaround for replace: false in vue 2.0 ?

Hi, is JSX already usable?

@reohjs - No and I would personally see that as a real step backwards for Vue, if it did support JSX.

Scott

@reohjs In Evan's stream last night he mentioned it could be made with a plugin so i imagine once this goes into beta it wouldn't take long for someone to create it. I'm happy that it's not in the core but a JSX plugin sounds like a great idea.

I'm happy that it's not in the core

👍 👍 👍 👍

Yeah should be a plugin. However, as seen templates have a lot of benefits for standard components.

JSX compilation should be easy to achieve with this plugin: https://babeljs.io/docs/plugins/transform-react-jsx/

I think the _h function would be the replacement for React.createElement

What about providing an interface to create custom v-model modifiers as a way to replace 2 way filters? It seems they are already being used to parse user input (for example v-model.trim). If the parsing/ formatting is simple and independent from a specific data property, using a modifier would allow the parsing/formatting to be reused with much less boilerplate than by setting a computed property for each individual data property, or creating a new component for each input type where we want the parsing/formatting to be applied.

Hi, I'm currently working on a plugin to support gettext in Vue.js 1.0 and I have a directive that is using vm.$interpolate.

I'm wondering how to migrate my code to 2.0 since:

  • vm.$interpolate will be deprecated
  • directives will no longer have instances in 2.0

Or is there a better approach than a directive?

import languages from 'src/plugins/translate/languages'
import translateUtils from 'src/plugins/translate/utils'

const translateDirective = {
  terminal: true,
  params: ['translateN', 'translatePlural'],
  paramWatchers: {
    translateN: function () {
      this.translate()
    },
  },
  isPlural: function () {
    return 'translateN' in this.params && 'translatePlural' in this.params
  },
  bind: function () {
    this.boundTranslate = this.translate.bind(this)
    this.msgid = this.el.innerHTML.trim()
    this.translate()
    languages.eventEmitter.on(languages.languageChangedEventName, this.boundTranslate)
  },
  unbind: function () {
    languages.eventEmitter.removeListener(languages.languageChangedEventName, this.boundTranslate)
  },
  translate: function () {
    let n = this.isPlural() ? parseInt(this.params.translateN) : 1
    let translation = translateUtils.getTranslation(this.msgid, n)
    this.el.innerHTML = this.vm.$interpolate(translation)
  },
}

export default translateDirective

Just throwing some short words since I'm new at Vue, just to say that I'm happy to see the reduction of the API in general or the _under-the-hood_ helpers. JavaScript is really powerful already, and with computed properties plus other reactive features of the framework almost everything can be achieved.

Kudos for this _next_ release! 🎆

@kemar I'm not that familiar with gettext, but I would simply extend Vue.prototype with a $translate method, and then do

{{ $translate('some.Key.path') }}

Has the ability to register assets with array syntax been removed from 2.0? Not working on alpha, just wondering if it's intentional or not.
i.e:

components: [compA, compB, compC]

I know ES6 has shorthand which looks similar, but there are some scenarios where the array syntax was useful.

I see you mention rendering to native interfaces on mobile with weex and I was wondering how easy it would be to make vue and Nativescript talk.

Something more along the lines of Nativescript for Vue would be either Weex, which you mentioned, or Quasar.

Scott

If there is no longer dispatch or broadcast how will a generic child component inform its parent of an event/change? This doesn't seem to fit the pattern of a global bus or vuex. Use case we use now is a range slider for search filters. The range slider component is generic and is a child of several different search filters. We currently use dispatch when a range slider has finished sliding, then the parent knows to trigger a search based on the change.

@jrenton inline listeners <child @some-event="parentHandler">

Great job guys.

In my point of view, all the changes say that the best approach is to create your component tree based on only a "one way flow", that is so much more simple and easy to debug and maintain.

Without this, your data truthness would be inverse proportional off how far you are from the top most component.

Just want to say that:

render (h) {
    return (
    <div>
      {this.things.map(thing => <Thing thing={thing}></Thing>)}
   </div>
 );

Makes me happy

Is it expected that more will be added to this list before the release of 2.0? Just curious being as the issue is still open.

@zephraph Yes, we are continuously updating the list as we make updates to the API. 😃 Nothing huge so far, but occasional breaking changes from previous alphas.

I have a case, I used event dispatching in the past and where I'm stuck with vuex: The parent component has a list of child components and the child was dispatching an event when it's value changed so the parent was able to do something as a reaction of that change.
Now I tried to have an array of the child values in the vuex store. The thing is, how does the child component know in the getter, and in the action, what element of that array it needs to update. As far as I see, vuex does not provide functionality to dynamically get or trigger a mutuation of a value, or am I wrong about that?
What would be the best way to handle this case without event dispatching?

With $broadcast being removed, how would you tell a direct child to do something when a particular thing happens? This would be a scenario where no data has actually changed, so reactive props don't seem to fit.

I could use a prop and pass down a timestamp or some random data and watch that prop in the child but that seems strange. A global event bus would require generation of unique IDs so the the child is only reacting to events from it's parent and not any other instance of the parent component.

There's $emit in a child which a parent can listen to using an inline listener, is there anything for the other way round?

I could pass down an instance of an emitter via a prop, then emmiter.on in the child, does that sound terrible?

@gwildu actions can take arguments, so you can pass item id along with the action. And instead of making the item component fetch the corresponding item from the store, fetch the list in the parent, and pass item data to the item component with a prop.

// Vuex store
state: {
  items: [],
},
mutations: {
  ITEM_REMOVED: function(state, id) {
    var io = state.items.findIndex(item => item.id === id);
    state.items.splice(io, 1);
  },
},
// within the parent component
vuex: {
  getters: {
    items: state => state.items,
  },
  actions: {
    removeItem(store, id) {
      store.dispatch('ITEM_REMOVED', id);
    },
  },
},
<!-- within the parent template -->
<item v-for="item in item"
  :item-data="item.data"
  @removed="removeItem(item.id)"
>
</item>
<!-- within the child template -->
<button @click="$emit('removed')">Remove</button>

If your items do not have a locally unique ids, you can generate one when the item is created or received from the API. Most of the time cuid is good enough for that.

@fergaldoyle due to the parent always knowing it's children, you can put v-ref:some-child on the child to get the reference to the child's vm, and then either $emit on it, or just call a method directly with this.$refs.someChild.<methodName>(...).

However I would advise rethinking the architecture in that case, because events flowing down make the component really hard to reason about.

I was playing around with vuejs 2 and I noticed for Snabbdom if you pass

h('div', {style: {color: '#000'}}, [
  h('h1', 'Headline'),
  h('p', 'A paragraph'),
]);

To the render function you get

<div style="color:#000;"><h1>Headline</h1><p>A paragraph</p></div>

But in vuejs you get

<div style="color:#000;"><h1></h1><p></p></div>

Is there a way to modify the text content (inside <h1>)?

@dubcanada why not just pass those as children?

Right that would make sense. Thanks

Hi. I have some question about transition system in Vue 2.0 or rather a proposal because I don't see it being in the plans for Vue 2.0. In Vue 1.0 i often encountered the need to detect when some transition/animation i have set up would end. Now I do this by using setTimeout, but this is very hacky and ugly way, we can all agree. So my question is, will be in Vue 2.0 some way to detect the end of CSS transition when we use transition combined with v-show/v-if, possibly via event?

<my-comp v-show="isVisible" @transition-end="onTransitionEnd" transition></my-comp>

i would be very happy to see something like this in next Vue release :) thanks for hearing me out

@sqal you can do that with transition hooks: https://jsfiddle.net/simplesmiler/Lrk9sxjf/97/

@dubcanada it will be supported in the next release (omitting data when creating element)

Thanks @fergaldoyle and @simplesmiler for your hint to emit.

I was not aware, the parent is able to listen to events that were emitted by the child. Of course it makes more sense to listen to that non-bubbling event then.

Hi all. A bit of background: we are working with webgl and I would like to do some interfaces on a 3D surface. This means that we need to render an interface to for example a canvas and then convert the content of the canvas to a texture.

I have been working with Angular, React and Vue and to me Vue just makes the most sense! While reading about React I came across the react-canvas project. The interesting thing is that instead of transforming the virtual DOM into real DOM nodes, they draw it to a canvas.

Because Vue 2.0 is also using a virtual DOM I was wondering if something like this can be done as well?

Hello,

Just some clarification of the removing of .sync and what a generic workflow for handling props on a generic component might look like.

so, going from
<component :value.sync="some.value"></component>
to
<component :value="some.value" @update="updateSomeValue"></component>

What is the recommended way of tracking the prop value?
In the most basic case, it seems to be

props: ['value'],
computed: {
    _value: {
        get(){
            return this.value;
        },
        set(newVal) {
            this.$emit('update', newVal);
            return newVal;
        }
    }
}

But, surely this relies on the parent component returning that value to the prop, so when the component gets it again, it reflects the most recent change...

Does that mean we now need to do something like this:

props: ['value'],
data() {
    return {
        _val: this.value
    }
},
watch: {
    value(newVal) {
        this._val = newVal;
    }
},
computed: {
    _value: {
        get(){
            return this._val;
        },
        set(newVal) {
            this._val = newVal
            this.$emit('update', newVal);
        }
    }
}

This seems like a lot of boilerplate to handle the passing in (and changing) of a value, notifying the parent that the value has changed, and tracking the change internally, in case the change isn't propagated back by the parent.

Or am I missing a bit of vue magic reactivity here?

Also, there is a chance that if there are a lot of props to handle, this could get quite complicated.
I could almost see myself working out a wrapper-component, where children access this.$parent.value in order to mutate directly, and the wrapper-component just handling the props/computed/watches

@Towerful what exactly do you mean by "tracking the value"? And why do you want setter style (this._value = newValue) instead of explicit this.$emit('value-updated', newValue)?

The power of one-way flow is that the parent can decide to not apply the change requested by the child, or can mark the child as "on hold" and apply the change later (e.g. after checking back with the server).

@simplesmiler using a computed property allows you to bind it in the template, no? so you can use v-model.
And having the setter & getter contained in 1 place makes it easy to go and see the functionality when the value gets updated, as opposed to having different ways to access the value and mutate the value within the component, and scattered throughout the code.
If using the explicit way within a model, and not using setters, it seems like the methods object is going to be cluttered up with updateValue type methods for the template, as opposed to actual methods.

I guess it applies where the user selects an option in a component, and the component relies on that value to show what is selected.
You are relying on the parent component passing that back into the component for it to be able to do that.
Unless, when the user selects an option, you trigger the component display update manually. Which seems to be moving away from Vue's reactivity.
So having an internal value track what it 'should be', have the template react to that. Use setters/getters to wrap the property to track internal changes & raise external events, and a watch on the property to update the internal value when it is changed externally.

Perhaps I am just struggling to get my head around the new way of doing it.

@Towerful - You aren't the only one....

Scott

@Towerful:

To me it seems that what you describe are essentally components that act like inputs with a v-model: the user changes some value in the UI, and you want that change to be reflected in the bound data immediatly.

For these types of components, you can use v-model on comonents in 2.0:

<my-input v-model="myValue">

// in my-input.vue
<input :value="value" @change="$emit('input', $event.target.value)">

export default {
  props: ['value']  //special prop received from v-model
}

This makes the interface to real <input> elements and to custom input components essentially identical, and a two-way binding.


For more complex components that receive multiple props (and are not simple custom inputs, but more abstract), we discourage using .sync because it becomes hard to reason about in most situations.

The parent should decide what to do with a value it receives from the child, it'S data should not be implicitly changed like .sync does.

Can you provide an example that is _not_ solvabel with the v-model approach above and still beneftis from using .sync? That may be a better foundation for discussion than abstract theory.

Oh, how did I miss that?! Its definitely there in the OP, and there is even a discussion about this some comments ago! Now I feel a bit stupid.
Could the original post be updated to make it a little more clear that v-model can be used on a component?
@LinusBorg Off the top of my head, I cannot think of a case where v-model on a component would not work. I missed that part in the original post.
Even for complicated object components, it would just be a matter of nesting components. And this re-enforces single responsibility components.
It makes a lot more sense :)

@Towerful

Re: using v-model. The thing is, v-model is synchronous (in a way), while the cross-component data flow is inherently asynchronous because of the watcher queue (demo). I've seen this confuse a lot of people. One-way flow just makes it more explicit that props are not synchronous and forces you to not rely on them being synchronous (this is what you are trying to trick your way around).

Re: cluttered methods. For simple cases you can always do @value-updated="value = $arguments[0]". For complicated cases it's a good thing to have a method, where you can adjust the state to keep it consistent (e.g. trigger updates manually). Segway to the next point.

Re: moving away from reactivity. I don't agree with this statement. For simple cases you don't need magic to make the child pick up the value, updated by the value-updated="value = $arguments[0]".

For complicated cases, with .sync props you would have to use watch, but explicit watch is not really a part of reactivity. It's an escape hatch, where you trigger your manual updates that can not be expressed as computed. And it's not a good one, because it can not react to changes synchronously, like computed can. This is why when using watch heavily, you may find your data updates taking a few "ticks" to propagate. If you ever stumbled upon directly nested nextTick, you know what I'm talking about.

Now, -updated handler provides a better escape hatch, letting the complicated model changes be applied synchronously (or simultaneously asynchronously) after child expresses the intent, making sure that child will receive updated values in the next tick (or will not receive inconsistent state).

@yyx990803 Could we implement a way to listen for $emits, similar to how we had events for $dispatch and $broadcast in vuejs1?

Feels more vuejs-esque, something along the lines of this (an 'on' or 'listen'):

Vue.component('cart', {
  template: "#cart-template",
  data () {
    return {quantity : 0 }
  },
  watch: {
    'quantity': function (quantity, oldQuantity) {
      console.log('quantity changed from %s to %s', oldQuantity, quantity)

      bus.$emit('cart.quantity-changed', quantity)
    }
  }
});

new Vue({
  el: '.container',
  data : function () {
    return {
      quantity: 0
    };
  },
  on: {
    'cart.quantity-changed': function (newQuantity) {
      console.log('quantity change emitted');

      Vue.set(self, 'quantity', newQuantity);
    }
  },
  computed:{
    gold: function(){
      return this.quantity * 100
    }
  }
})

This basically would automatically attach itself to the global bus.

Event Busses are not a pattern that we want to encourage - it is only useful some edge cases. Generally, a store pattern, like vuex, is preferred.

Implementing an API that makes using a bus easier and feels "officially supported" would be the wrong signal.

Looking at your example, if you stored the quantity in a store accessed by both components, no events would be nessessary. The computed property in the container component would update automatically.

Simple example code without using a real store solution like vuex:

var store = {
  cart: {
    quantity: 0
  }
}
Vue.component('cart', {
  template: "#cart-template",
  data () {
    return store.cart
  },
});

new Vue({
  el: '.container',
  data : function () {
    return store.cart;
  },
  computed:{
    gold: function(){
      return this.quantity * 100
    }
  }
})

I would say the general idea of vue2 is to make it harder to shoot yourself
in the foot.

On Sun, Jul 3, 2016 at 11:24 AM, Thorsten Lünborg [email protected]
wrote:

Event Busses are not a pattern that we want to encourage - it is only
useful some edge cases. Generally, a store pattern, like vuex, is preferred.

Implementing an API that makes using a bus easier and feels "officially
supported" would be the wrong signal.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/vuejs/vue/issues/2873#issuecomment-230158828, or mute
the thread
https://github.com/notifications/unsubscribe/AACoukCpCgYlDbVej_w_h4NEhQ-imYHBks5qR9QwgaJpZM4IedHC
.

@kharysharpe $emits are intended to be listened with v-on on the child instance. This also has an added benefit of being able to tap into the original context of where the instance is used:

<list-item v-for="(item, index) in items"
  :title="item.title"
  @remove="items.splice(index, 1)"
>
</list-item>

Is there a date for the 2.0 release? I'm pretty excited with the changes. Congrats!
I'm thinking on using Vue 2.0 + Redux.

@Sendoushi No date yet on the final release, but beta may be within a week. 😄 Vuex 2.0 is also being developed alongside and it will not only feature a much simpler API than current vuex, but also integrates into Vue ecosystem much more nicely than redux.

Vuex 2.0 is also being developed alongside and it will not only feature a much simpler API than current vuex, but also integrates into Vue ecosystem much more nicely than redux.

@chrisvfritz That's fantastic to hear! I always felt the current API is a bit overly and unnecessarily complicated. Ended up having to do things like this to compensate:

const mutations = {
  LOGIN (state) { state.loggedIn = true },
  LOGOUT (state) { state.loggedIn = false }
}

export const types = Object.keys(mutations)

// For now we dynamically generate all the actions like this.
// It's rare when anything more complicated is needed, but there
// is an example here:
// http://vuex.vuejs.org/en/actions.html
export const actions = types.reduce((o, el) => {
  var action = S(el.toLowerCase()).camelize().s
  o[action] = ({dispatch}, ...args) => dispatch(el, ...args)
  return o
}, {})

What about the roadmap of vue 2 and vuex 2. Is it planned to release them together or one before the other and what about the compatibilities of different versions?

Relating to question above, what is the status with vue-router -- is it going to get Vue 2 support soon or will Vue 2 testing need to be done without the router?

@gwildu They'll likely be released somewhat together and Vuex 2.0 will only support Vue 2.0. Pre 2.0 Vuex will still receive support until Vue 1.x is no longer supported.

@Uninen Vue Router will be receiving some love next, before the release of Vue 2.0.

Thanks for the nfo @chrisvfritz :)

@chrisvfritz @Uninen correction: Vuex 2.0 also works for Vue 1.x.

Next major version of vue-router will only support Vue 2.x.

Runtime only build: since it doesn't include the compiler, you need to either pre-compiled templates in a compile step, or manually written render functions.

Is there / will there be a way to precompile templates without using vueify/vue-loader and .vue files? If not, would it be a good idea to have a babel plugin to transform template: properties to render functions in components?

升级2.0后,deprecated的特性还能用不
可以先升级2.0,然后再慢慢把deprecated的特性改掉不

Will it be possible to create a terminal component, now that elementDirective is gone?

As mentioned:

v-model no longer cares about initial inline value. It will always treat the Vue instance data as the source of truth.

Consider that

<child-component>
  <input type="checkbox" :id="_uid" v-model="childModel" :value="value" />
  <label :for="_uid"><slot></slot></label>
</child-component>

How can I deal with checkbox with arrays between custom components?

_Updated 1:_
Solved. Transfer prop type="checkbox" to the child component in the parent component.

<parent-component>
  <child-component type="checkbox" v-model="parentModel" value="apple"  />
  <child-component type="checkbox" v-model="parentModel" value="orange" />
  <child-component type="checkbox" v-model="parentModel" value="banana" />
</parent-component>

Then you can get inline value via {props: [ 'value' ]}.
Emit a change event to the parent component to tell the value has changed.

<child-component>
  <input type="checkbox" :id="_uid" v-model="childModel" :value="value"
    @change="$emit('change', $event)"
  />
  <label :for="_uid"><slot></slot></label>
</child-component>

This is because the compiler compiles the v-model directive according to its type. And the compiler will generate the checked prop and bind a change event to it.

_Updated 2:_
However, the updated life cycle hook doesn't trigger due to v-model directly changes the checked attribute (That means you can't get a change event of a native html checkbox component by modifying the value of v-model).
So, @yyx990803, can you trigger a change event after v-model changes?

@YunSun-CN The only way that I was able to get around your issue was to add a property specific for the value, ala val, and use that to set the actual value, and then just emit changes to the v-model 'input' event.

@johnleider I wrote a custom directive to simulate what v-model does.
By the way, you should generate models in a strict way not only checking type prop but checking element's tagName. Otherwise, another custom component with type prop may overwrite its default model behaviour.

Hi. Do we know a release date?

@thanosalexander We have not decided on a date yet, no. We just introduced some major breaking changes to the Transition system with 2.0.0-bet.2, which have to be throughly tested. So it will still be a couple of weeks until we can think about a release, in my opinion.

ok..i 'll go with this then ..i dont think the step to the stable will be too big! thank you

What about the docs? One of the reason Vue was early adopted was the documentation and it's the only reason holding me back now with v2. I saw the issue following up docs, but don't see is getting any close to get finished soon. Probably I'm ignoring so much going on under the hood, reason why rising the question :)

Any plans to implement transition-mode outside of component switching in 2.0?
https://github.com/vuejs/Discussion/issues/156

@miljan-aleksic Docs will be ready when 2.0 will be officially released. We are still in beta. ;)

Until then, you can follow the progress on documentation here (or even contribute)

@aristidesfl Already done. 🎉

@miljan-aleksic Adding to what @LinusBorg mentioned, most of the new guide is already complete and you can even read the source here if you'd like. Keep in mind though that as of writing, it hasn't been fully updated to reflect changes in beta.2, significant peer review is still to come, and there are some other minor API changes that are being considered. So unless you want to help fix typos and improve explanations, I'd recommend waiting until we officially publish (maybe in the RC stage).

We also agree that the excellent documentation is a vital part of Vue. Even Dan Abramov from the React team loves our docs. 😄 That's why it's one of my personal goals that the 2.0 docs are _even better_. In the meantime though...

For anyone who wants to learn about 2.0 early, I'd recommend the feature unit tests as the most up-to-date resource available.

That's one of my primary resources in writing documentation and they're generally quite readable if you're familiar with Jasmine.

Thanks @chrisvfritz, very useful information. I will give the new docs a shot, taking in consideration its a WIP, and feedback as required. It's time to get serious about Vue 2.0 ;)

createElement in the render function using on doesn't seem to handle arrays (like snabbdom does) is there a way to pass data to the called functions?

For example in snabbdom I can use

{on:{click: [function, dataToPass]}}

And the function will get dataToPass as the first argument. But this seems to error out in vuejs 2 beta 2 Uncaught TypeError: arr[i] is not a function. Is there a way to pass data & the event using the on from create element?

@dubcanada the event handling in Vue 2.0 is different from snabbdom's - you have to curry the function yourself. The array syntax simply attaches multiple handlers to the same event.

I am trying to get the slots content as string instead of rendering them. With standard nodes there is an easy workaround, but with Vnodes I didn't found a way. Is there any workaround for it?

@miljan-aleksic Try rendering it, getting the element's content with innerHTML, then hiding the element with display: none in css.

Thanks for the help. If I render it, the final output would be different. I am creating a component that will wrap its child contents with a pre tag and encode the HTML.

In that case, render the output in a different element from the original.

Though I'll make the point that templating shouldn't be your way of writing your content. It should be the way in describing _how_ the content is written, and not the content itself. I'd recommend storing the text as a string in JS (or as a resource somewhere else in your project, _especially_ if it's user input of some kind), then passing it into the child as a prop, which should make things a thousand times easier anyway.

You are right @Kingdaro, the best is to don't mix concepts and keep it simple. It was nice to have the syntax hihgligthig, though :)

When using the v-on directive the $arguments variable is not available anymore. I don't see any reference on that change here. Is a bug or missing reference?

@miljan-aleksic just use arguments.

Must be a PHP dev (like me)... I know how you feel. LOL!

Scott

@yyx990803, @smolinari I am... and an embarrassed one now haha. I made my self believe that I already tried that... seems I didn't well enough. It's working, thanks and sorry for waisting your time.

I was about to open a ticket about another "issue" but not sure anymore if it is... When using ref the registered component or element is not available immediately, so something like this would not work.

<button ref="button"...></button>
<foo :connect="$refs.button"></foo>

At the time Foo is getting rendered $refs.button is still undefined. In Vue 1 is working as expected. What am I missing this time?

You are missing that you should not pass DOM elements or component instances as props...

Why is that a bad idea? Let's say I have a Dropdown component which I want to connect to a Button (the trigger). Both are independent components and instead of connecting them through a query I am passing the reference directly.

@miljan-aleksic it's even better to connect them via state:

  • open/close state is maintained in their common parent
  • the parent pass the state down to the dropdown as a prop
  • the parent listens to the button's event to toggle the state

This way the dropdown and button are completely decoupled, the button can be reused to control other types of components, and the dropdown can be controlled by other types of input components.

Is not easy to get rid of old habits. Should I blame jQuery or mainly me? :D

Your approach, Evan, is correct. I will go that way even if it means the Dropdown integration would be more tedious. As the parent component would have to know about how to listen to the different events, not only about opening but closing the Dropdown when clicked outside but not the dropdown it self, etc. Many events and workarounds that the Dropdown was solving.

As the parent component would have to know about how to listen to the different events, not only about opening but closing the Dropdown when clicked outside but not the dropdown it self, etc. Many events and workarounds that the Dropdown was solving.

It still can? you can totally do addEventListener('body', ... ) from the dropdown component to register outside clicks etc... The dropdown can simply emit a 'close' event for the parent when someone clicks outside, for eample.

Yep, yep. Time to refactor some components :) Thanks everyone! Awesome community.

How does one apply v-model to a component with createElement? I took a look at the generated code using the template compiler, and...it's a lot of code. I didn't quite understand the documentation there about directives.

By default, a compile-time directive will extract the directive and the directive will not be present at runtime. If you want the directive to also be handled by a runtime definition, return true in the transform function.

@blocka you don't have access to built-in directives if you are using the render function. You will have to handle the equivalent logic yourself. For example v-if is just a ternary expression, v-for is an array.map() expression... and v-model (on a normal <input> element) is translated into a value binding and an input event listener.

@yyx990803 that's what I figured. I will probably wind up handled that with an HOC (I am already handing conditionals the same way (although I am thinking about using this)

With vue 1 there were two stated advantages of vuex vs redux.

  1. Performance is better as vuex mutates the state, which works best with vue (replacing old state had performance equivalent to "dirty checking")
  2. Vuex is more "aware" that it is in a vue application

Does using the virtual dom mitigate some or all of 1?

@blocka it does mitigate some of it, but the overall perf will still be much better than with Redux.

What changed in 2.0 is the granularity of the reactivity. Let's make a comparison:

  • In Vue 1.x, the reactivity is very fine-grained. Every directive and every text binding has a corresponding watcher. This results in fine-grained updates when data changes, but at the cost of more dependency tracking overhead on initial render, and slightly higher memory usage.
  • With Redux, the reactivity has no granularity at all. Whenever anything changes, the whole app needs to be re-rendered. In React, the Redux binding does some optimization on connected containers, but the user still needs to extensively implement shouldComponentUpdate to gain better performance.
  • In Vue 2.0, the reactivity has a medium granularity. Each component has a corresponding watcher that keeps track of that component's dependencies. When data changes, only components that depend on the change will need to re-render their virtual DOM. This is essentially the best case scenario for React, but you don't need to do anything to achieve that in Vue 2.0.

Generally with 2.0, you will see (compared to 1.x)

  • slightly slower (but still very fast) updates for small data changes
  • decently faster updates for medium to large data changes
  • significantly faster initial render

Hey,
i don't get transitions with animated.css to work.

<transition enterClass="fadeIn" leaveClass="fadeOut" class="animated" mode="out-in"> 
  <router-view keep-alive></router-view> 
</transition>

Does somebody have an idea?

Your prop names are wrong.

camelCase vs kebap-case still applies in 2.0.

<transition enter-class="fadeIn" leave-class="fadeOut" class="animated" mode="out-in"> 
  <router-view keep-alive></router-view> 
</transition>

@LinusBorg I'm sorry, I already tried that. Here I have a small fiddle. With css transitions and the name tag it works fine.
https://jsfiddle.net/z0nyfba0/

When using v-model on a component, will the component have visibility to any modifiers used with v-model?

e.g. if I have a component that emits an input event, when that event is emitted is dependent on whether the lazy modifier is used or not.

@fergaldoyle i played with this a little and i think you can't use v-model modifiers on custom element since you need to manually emit input event. If you want to achieve lazy behavior you need to bind change event to the input e.g. https://jsfiddle.net/cynhtLty/1/

@calebboyd

https://jsfiddle.net/Linusborg/z0nyfba0/1/

  1. You have to use enter-active-class and leave-active-class
  2. You have to put class="animated" on the <router-view> element.

@fergaldoyle According to the 1.0 docs, I think with lazy, v-model would just react to change instead of input. You can use this to change the behavior, and emit input or change to give the different results depending on whether lazy is given or not.

I've been scratching my head while playing around with a simple v-for example. For some reason the value binding isn't working for select elements in 2.0: https://jsfiddle.net/972eL5fL/

Also it should probably be noted in the docs that v-for ranges like "i in 10" start from 1 instead of 0 as in 1.0.

@lauritzen

I've been scratching my head while playing around with a simple v-for example. For some reason the value binding isn't working for select elements in 2.0: https://jsfiddle.net/972eL5fL/

It seems to work as expected for me, what is not working for you?

Public Service Announcement

We encourage you to ask support questions on the forum or on gitter.

This issue should be reserved to discussions about the new API. If we handle support for various questions in here, this will get out of hand.

Thank you.

Why vm.$get has been deprecated?
Why not Vue.get instead?
It is very useful for evaluating computed exressions like this
var exp = 'entity.type.name' // this is generated in runtime return vm.$get(exp)

@iagafonov there's not a lot of scenarios where this is useful, therefore it should not be part of the core.

If you need the functionality for one of the few scenarios, you can very easily add a similar behaviour with the help of e.g. lodash:

import get from 'lodash/get';
Vue.prototype.$get = get

//in any component
var value = this.$get(this.someObject,'some.path.to.value')

(of course your could also add it as "class method" as Vue.get() - or simply import it locally where you need it -your choice)

@LinusBorg. First of all, i don't use lodash or something like this.
Secondly lodash implementation is slow, because it is in run-time try to deep down into exression structure. vue complies new specified function (by parseExpression), binded to the scope.
It'is not trivial part, it is very difficult to reimplement this.
Of course, $get compile function every time ). Will be nice if parseExression be part of api in Vue.util, for example.

@iagafonov this.$get also has to parse the path at runtime and retrieve the value dynamically. Otherwise you'd get an error if the path does not exist. Also the perf difference will be negligible in most cases. If you don't want lodash there are plenty of other path retrieval libraries out there. It just isn't part of Vue's concern anymore.

What are some alternatives to the now deprecated param attributes?

are you talking about params in a directive? Then you can find all binded attributes inside vnode object

<button v-test="123" color="red" type="button">click me</button>

bind (el, binding, vnode) {
 // vnode.data.attrs -> { color: 'red' }
}

@sqal, is this in reply to my question? If so, I am talking about param attributes such as lazy, number, and debounce. For instance, prior to 2.0, I could do this <input type="text" v-model="msg" number> (number being a param attribute here). How can I get the same results without using param attribute?

@p-adams it's mentioned in the post - they are modifiers now <input v-model.number="msg">

I find in Vue 2.0, when the props change, the render function is always called, so I wonder will 2.0 support shouldComponentUpdate to decide whether re-render.

@yyx990803 Okay, I see it now in the post The lazy and number params are now modifiers.

@HeChenTao thhe render function is not "always" called, only when it's required:

  • Vue does not need shouldComponentUpdate, because of its Reactivity.
  • When reactive data that is used in a component is changed, this willl trigger the render function, vdom diffing and so on.
  • But if none of that data changed, not update is nessessary and the render function will _not_ be called.

The same thing can be done in react with mobx. I'm fairly certain that you don't have to implement shouldComponentUpdate. However, like vue, mobx insists on a mutable state. If, for some reason, you've bought into the immutable state concept. In that case, react has your back with shouldComponentUpdate.

So does that mean if somebody insists on an immutable state, vue is not going to be a good match?

The context argument of the Functional Components have children plus slots. I find it a little bit confusing knowing that children() and slots().default its exactly the same. Makes me wonder what is the correct approach. Probably 'children' as slots is lazy, but still why supporting two different ways of getting the same behaviour?

Functional components are just functions and thus they don't have childrens. IMHO, childrens should be deprecated and just keep slots as not lazy.

@blocka you can implement reactive data in react with mobx, true. But reactivity is at the core of Vue's functionality. So if that's not one's cup of tea, that person is at the wrongparty.

@miljan-aleksic children is raw (you get every node regardless of what slot they should go into), slots will be resolved based on slot names on incoming children.

Thanks @yyx990803. Maybe more details about this in the docs would avoid confusions, @chrisvfritz.

@miljan-aleksic I'll add a note. 👍

Regarding filters, using a computed property seems straightforward enough, but how to handle the case of using filter with v-model. If one wants to filter through a list of names by typing in input field, how can this be done in 2.0?

Thoughts on having Vue warn when a data field / computed property isn't being used in a template? I imagine there are some limitations here, but it'd be super helpful to know where I could afford pulling out some useless store imports where they aren't needed.

@yyx990803, what do you think about setting $context reference to the Component prototype? The same as with $parent or $root I found my self often accessing the context which is currently only available through the $vnode object.

Actually that doesn't seems to be a reliable way to access the context. How should be done?

@miljan-aleksic Can you share the use cases where you're frequently accessing the context?

@Kingdaro Can you open an issue for that? It sounds good if it'll be feasible.

@p-adams You can still use a computed property with Array.prototype.filter.

@chrisvfritz, basically for workarounds as for example to set variables in the context that the child is expecting. Or to set a ref to the component earlier that Vue it self does.

I agree is not common to all, but at least there should be a reliable way to access it within the component. The $vnode is not present until the component mounted when using templates (at least my conclusion so far).

I would content knowing how to access it in a proper way.

Another situation where $context would be useful is when reusing a component as root of another component.

<template>
  <Foo>
    <child/>
  </Foo>
</template>
<script>
{ name: 'Bar' ... }
</script>

In the example child.$parent would return component Foo instead of Bar, which si correct but if the parent and child are dependent of each other a direct communication between them could be through the context.

@miljan-aleksic I'll leave this one to @yyx990803. I would say that just like with $parent, reaching for $context will probably be the wrong way 99.9% of the time and I think I'd probably never use it.

I have a situation with v-show and transitions. In this scenario there is a modal which by default is to 'display: none' in the CSS. When combined with v-show it would never be shown becasue the directive removes the display property, the CSS ones then persist. I can't change the CSS (project requirements) and I can't use a custom directive as seems Vue transitions relies specifically on it.

I am thinking now that a directive that evaluate right after v-show could set the display property to block. Need to try that out but anyway it could be a good idea to add a modifier to v-show to allow setting display to block or inline-block. Just a thought.

@chrisvfritz, it is expected that for functional components the parent reference is not the immediate parent where they are being used as slots, but the context component instead?

Compilation of template fails if it contains "<" (and possibly other html-sensitive characters) in 2.0.0-beta7

https://jsfiddle.net/x0r59ur1/

This worked in 1.0.26.

Escaping "<" with "<" solves the issue.

@GlurG it's expected to escape "<" properly.

@yyx990803, if I want to use transitions on a list of components of the same type and keep their state, how should I do it? Following the docs I only see how when the components are different.

Lets say a Tab component and transition its items. I can't find a way :(

<tabs>
  <transition>
    <tabs-item>Content 1</tabs-item>
    <tabs-item>Content 2</tabs-item>
    <tabs-item>Content 3</tabs-item>
  <transition>
</tabs>

@miljan-aleksic <transition> is for single element only. You need <transition-group> for multiple items.

@yyx990803, tried that one as well, but still don't see how to achieve it. Transition-group works by adding/removing elements but while doing so the components would be inited again, losing the state. Beside the idea of a Tab is to show only one component at a time, its not exactly a list :)

@yyx990803, @LinusBorg I appreciate the help but the solution is not obvious. I know how the transitions are applied, what I can't figurate out is how to keep-alive the transitioned components.

I have created a new issue for clarity sake with jsfiddle example on it how the components are created each time.

@yyx990803, thank you so much for improving the keep-alive feature, now it works as expected.

You are literally changing my life, with your products and works ethics I am able to learn, build and deliver products that I had long time in standby. With your keep it simple approach, high tech is available to everyone to use and build upon. For all that and more I am eternally gratefull.

@miljan-aleksic There's a Patreon campaign wink wink.

You know what @phanan, you are totally right. I have started supporting Evan personally and as soon as the company products start giving results will make sure the support becomes more noticeable.

The ready lifecycle hook is deprecated in favor of mounted; but according to the changelog there is no guarantee that the component will be rendered before mounted is called. This causes sporadic errors when I want to initialize certain jquery components (like selectize) after the component has initialized. Which lifecycle hook should I use instead? Can the "ready" hook be emulated like this:

function mounted() {
  Vue.nextTick(() => {
    //...
  });
}

@GlurG Yes, that will work. And by the way, that was also nessessariy with ready'() in 1.0 in many cases.

Is there any reason there can't be a hook for this regardless? I've also
across this...even in 1.0, and resorted to things like looping with raf to
check if its in the dom, etc.
On Aug 10, 2016 6:26 PM, "Thorsten Lünborg" [email protected]
wrote:

@GlurG https://github.com/GlurG Yes, that will work. And by the way,
that was also nessessariy with ready'() in 1.0 in many cases.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/vuejs/vue/issues/2873#issuecomment-238903012, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AACounAoI8p65soUUrbdaiwteDXKgMGJks5qee25gaJpZM4IedHC
.

When using the render functions the core directives are ignored, which is reasonable. But some are not so easy to reproduce using plain js, as the v-model which has workarounds for IE9 and probably solves other edge case issues.

It makes you reconsider using a template instead, but thats not possible or the best option in some situations. The docs could definitely offer more guidance on this topic and besides it could be a good idea to have some helper when working with render functions which would help solving these common situations and make no one miss a template.

@miljan-aleksic sorry, i deleted my comment because i noticed it's only works for v-show or custom directives, and yeah, as you said in case of v-model, it's required to add input/change listener and update our data manually

is the new activated hook supposed to be called when a route is fired that activates/mounts a router-view? Im not seeing this behavior currently.

@wprater no, it's solely related to <keep-alive> and nothing else.

@yyx990803 Im wrapping my router-view in a keep-alive, but I cannot seem to find a hook for when I route back to the pervious view. mounted nor activated are called. I need to be certain the dom is rendered.

@wprater please avoid using this thread for unrelated questions. If there's a bug, file issue at corresponding repo with reproduction.

Does Vue JSX support the object spread operator ? I've tried it but it doesn't work.

It does and @yyx990803 put in a lot of effort to get it working.

I'm doing this <Component {...{ props } }></Component> and it works as documented.

@blocka Thanks ! I thought the property name props was not needed 😂

@yyx990803
components options don't support array type, but it is work in 1.x.

e.g.

var Parent = Vue.extend({
  name: 'parent',
  template: '<div><slot></slot></div>'
})

var Child = Vue.extend({
  name: 'child',
  template: '<span>hello</span>'
})

new Vue({
  el: '#app',

  components: [
    Parent,
    Child
  ],

  replace: false,

  template: '<parent><child></child></parent>'
})

It's bug?

@QingWei-Li they are simply not supported anymore, since it was never an officially documented feature. The reason is that with ES2015 you can just write components: { Parent, Child }.

just a small suggestion,
is there any chance for the normal array iteration we use v-foreach and for range we use v-for.

which will make more sense for users coming from php and even consistent with .each in JQ or foreach in JS

@ctf0 We are in RC stage, the API will not change anymore. And we won't introduce alternative syntax for doing the same thing either.

I don't think that the mental overhead of v-for="item in items" is significant enough to warrant that.

With this new version, i would you handle this case.

I have a calendar component (coming from semantic ui), which uses a classic text input, and show the date in a human format (like "July 10, 2016" for example). With v1.0, i was using a two-ways filter to convert that string into a proper date so my object data was directly ready for submit. But since filters won't work anymore in v-model, how could i do the same thing now in v2.0 ?

Thanks

@shadowRR would it be possible to see some code?

@p-adams Sure. Here you go.

First, my filter, which is use on my v-model for my calendar input. It's only purpose is to write, when the value change, a proper date type to my data (postgres date).

Vue.filter( 'formatDate', {
        read( date ) {
            return date;
        },
        write( date ) {
            if( !date ) return null;
            return moment( date, 'D MMMM YYYY' ).format( 'YYYY-MM-DD' );
        }
    } );

And i would you use it like this on my component (the input has a calendar system which return my date in the human readable format)

<div class="required field">
        <label>Start date</label>
         <div class="ui calendar">
                 <div class="ui input left icon">
                      <i class="calendar icon"></i>
                      <input v-model="section.start | formatDate" type="text">
                 </div>
         </div>
</div>

I'd recommend reading @yyx990803's post here: https://github.com/vuejs/vue/issues/2756 where he discusses two-way filters on v-model. Also, it may be better to ask questions such as this here: http://forum.vuejs.org/

I missed the post you're talking about, gonna see that, thanks ;)

Hi,
I have some doubts in new life cycle hooks.
If I want to register an event handler when mounted, and deregister it before unmount, how should I make it work? Add checks & logics in created & beforeDestroy hooks?
In Vue 1.x I would use attached & detached hooks.
But in 2.0 there is mounted hook but no unmount hook. Feels a bit not corresponding.
Is there any reason why no unmount hook is provided?

@f15gdsy mounted corresponds to destroyed. There's no attached/detatched counter parts in 2.0 - you need to do the in-dom check yourself. If your events don't care about in-dom/off-dom then mounted and beforeDestroy are the appropriate places to do that.

When used on a custom component, v-on now only listens to custom events $emitted by that component. (no longer listens to DOM events)

I may have missed a few posts here, but what's the design decision behind this?
It would make binding simple click events on components very verbose..

1.0:

<foo @click="bar"></foo>

2.0:

<div @click=bar>
  <foo></foo>
<div>

@fnlctrl, use the native modifier: @click.native="bar".

@miljan-aleksic Thank you very much! I think this modifier should be added to Directives -> v-on -> modifiers in this issue

Could I use Koa(1.x or 2.x) as the server? Is there any problem on vue-server-renderer with Koa?

@yyx990803

import Vue from 'vue'

Vue.component('expanding', {
  functional: true,
  render (createElement, { children }) {
    const data = {
      props: {
        name: 'expanding',
      },
      on: {
        beforeEnter ($el) {
          $el.classList.add('collapse')
          console.log('beforeEnter')
        },
        enter ($el) {
          $el.classList.remove('collapse')
          $el.classList.add('collapsing')
          $el.style.height = `${$el.scrollHeight}px`
          console.log('enter')
        },
        afterEnter ($el) {
          $el.classList.remove('collapsing')
          $el.classList.add('collapse', 'in')
          console.log('afterEnter')
        },
        beforeLeave ($el) {
          $el.classList.add('collapsing')
          $el.classList.remove('collapse', 'in')
          $el.style.height = 0
          console.log('beforeLeave')
        },
        leave ($el) {
          console.log('leave')
        },
        afterLeave ($el) {
          $el.classList.remove('collapsing')
          $el.classList.add('collapse')
          $el.style.display = 'none'
          console.log('afterLeave')
        }
      }
    }
    return createElement('transition', data, children)
  }
})
        <a href="#" :aria-expanded="showItem ? 'true' : 'false'" @click="showItem = !showItem">
          <span class="icon is-small"><i class="fa fa-table"></i></span>
          Tables
          <span class="icon is-small is-angle"><i class="fa fa-angle-down"></i></span>
        </a>
        <expanding appear="true">
          <ul v-show="showItem">
            <li>
              <router-link to="/tables/basic">Basic</router-link>
            </li>
            <li>
              <router-link to="/tables/handsontable">Handsontable</router-link>
            </li>
          </ul>
        </expanding>

Why do not call the enter hook?

@fundon You should ask the question on the forums or the gitter chat

Locking this thread because:

  1. We are now in API freeze in RC so this document will no longer be updated.
  2. Too many people are using this as a general FAQ thread, which is not what it is for.

If you have a bug, please open a separate issue following the issue reporting guide, if you have a question, please use the forum or gitter.

Update: For a more definitive and detailed list of changes in 2.0, see the new migration guide.

Was this page helpful?
0 / 5 - 0 ratings