<h3 dir="auto">What problem does this feature solve?</h3>
<p dir="auto">example:<br>
[div &gt; SomeComponent &gt; large children DOM]</p>
<p dir="auto">Often we don't need SomeComponent features in some cases, just children - slot. And then we use v-if for it with v-else and duplicate a lot of child code. Also, we can use a prop like 'disabled' for SomeComponent, but still, component initializing anyway what impact performance. It is useful for Tooltips, Wrappers, etc.</p>
<p dir="auto">Right now it is possible to implement with render-functions, but it is very complicated and inconvenient.</p>
<h3 dir="auto">What does the proposed API look like?</h3>
<p dir="auto">My request is to add directive like 'v-if-only' which mean whether this component will render or just default scope slot.</p>
<blockquote>
<p dir="auto">This is a live document. Last update: 08/17/2016 as of 2.0.0-rc.2</p>
</blockquote>
<h3 dir="auto">General Notes</h3>
<ul dir="auto">
<li>A checked item means it has been implemented in the 2.0 development branch.</li>
<li>Features subject to change during development.</li>
<li>The breaking change list is not guaranteed to be complete during development.</li>
<li>There are some <a href="#upgrade-tips">upgrade tips</a> at the end.</li>
</ul>
<h3 dir="auto">High Level Changes</h3>
<ul dir="auto">
<li>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 (<code class="notranslate">&lt;script type="text/x-template"&gt;</code>, inline JavaScript strings, or compiled via single-file components), you are no longer subject to any of the <a href="http://vuejs.org/guide/components.html#Template-Parsing" rel="nofollow">template parsing limitations in 1.x</a>. However, if you are relying on mounting to an element with existing content as template (using the <code class="notranslate">el</code> option), you will still be subject to those limitations.</li>
<li>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:
<ul dir="auto">
<li>Standalone build: includes both the compiler <strong>and</strong> the runtime. This functions basically exactly the same Vue 1.x does.</li>
<li>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 <code class="notranslate">vueify</code> or <code class="notranslate">vue-loader</code> will perform the template pre-compilation.</li>
</ul>
</li>
</ul>
<h3 dir="auto">Global config</h3>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> Vue.config.silent</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> Vue.config.optionMergeStrategies</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> Vue.config.devtools</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> Vue.config.errorHandler <sup>new - global hook for handling uncaught errors during component render and watchers (default behavior is <del>logging the error stack</del> throwing in place)</sup></li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> Vue.config.keyCodes <sup>new - configure custom key aliases for <code class="notranslate">v-on</code>.</sup></li>
<li><del>Vue.config.debug</del> <sup>deprecated, no longer useful since warnings come with stack traces by default now</sup></li>
<li><del>Vue.config.async</del> <sup>deprecated, async is required for rendering performance</sup></li>
<li><del>Vue.config.delimiters</del> <sup>reworked as a component-level option</sup></li>
<li><del>Vue.config.unsafeDelimiters</del> <sup>deprecated, use v-html</sup></li>
</ul>
<h3 dir="auto">Global API</h3>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> Vue.extend</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> Vue.nextTick</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> Vue.set</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> Vue.delete</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> Vue.directive</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> Vue.component</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> Vue.use</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> Vue.mixin</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> Vue.compile <sup>new (only in standalone build)</sup></li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> Vue.transition
<ul dir="auto">
<li><del>stagger</del> <sup>deprecated, set and access data-index on <code class="notranslate">el</code> instead</sup></li>
</ul>
</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> Vue.filter</li>
<li><del>Vue.elementDirective</del> <sup>deprecated, just use components</sup></li>
<li><del>Vue.partial</del> <sup>deprecated, use functional components</sup></li>
</ul>
<h3 dir="auto">Options</h3>
<h5 dir="auto">data</h5>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> data</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> props
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> prop validation</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> default value</li>
<li><del>coerce</del> <sup>deprecated. If you want to convert a prop, setup a local computed value based on it.</sup></li>
<li><del>prop binding modes</del> <sup>deprecated (v-model can work on components)</sup></li>
</ul>
</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> propsData <sup>new, instantiation only</sup></li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> computed</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> methods</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> watch</li>
</ul>
<h5 dir="auto">DOM</h5>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> el</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> template</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> render <sup>new</sup></li>
<li><del>replace</del> <sup>deprecated, components now <strong>must</strong> have exactly one root element.</sup></li>
</ul>
<h5 dir="auto">Lifecycle Hooks</h5>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> <del>init</del> beforeCreate</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> created</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> beforeDestroy</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> destroyed</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> beforeMount <sup>new</sup></li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> mounted <sup>new</sup></li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> beforeUpdate <sup>new</sup></li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> updated <sup>new</sup></li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> activated <sup>new (for keep-alive)</sup></li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> deactivated <sup>new (for keep-alive)</sup></li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> <del>ready</del> <sup>deprecated, use mounted (there's no longer the guarantee to be in-document)</sup></li>
<li><del>activate</del> <sup>deprecated, moved into vue-router</sup></li>
<li><del>beforeCompile</del> <sup>deprecated, use created</sup></li>
<li><del>compiled</del> <sup>deprecated, use mounted</sup></li>
<li><del>attached</del> <sup>deprecated, use custom in-dom check in other hooks</sup></li>
<li><del>detached</del> <sup>deprecated, same as above</sup></li>
</ul>
<h5 dir="auto">Assets</h5>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> directives</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> components</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> transitions</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> filters</li>
<li><del>partials</del> <sup>deprecated</sup></li>
<li><del>elementDirectives</del> <sup>deprecated</sup></li>
</ul>
<h5 dir="auto">Misc</h5>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> parent</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> mixins</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> name</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> extends</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> delimiters <sup>new, replacing the original global config option. Only available in standalone build.</sup></li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> functional <sup>new, makes the component stateless and instance-less (just a render function that returns virtual nodes)</sup></li>
<li><del>events</del> <sup>deprecated, since no more event propagation</sup></li>
</ul>
<h3 dir="auto">Instance Properties</h3>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> vm.$data</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> vm.$el</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> vm.$options</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> vm.$parent</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> vm.$root</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> vm.$children</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> vm.$refs</li>
<li><del>vm.$els</del> <sup>deprecated, merged with $refs</sup></li>
</ul>
<h3 dir="auto">Instance Methods</h3>
<h5 dir="auto">data</h5>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> vm.$watch</li>
<li><del>vm.$get</del> <sup>deprecated, just retrieve values directly</sup></li>
<li><del>vm.$set</del> <sup>deprecated, use Vue.set</sup></li>
<li><del>vm.$delete</del> <sup>deprecated, use Vue.delete</sup></li>
<li><del>vm.$eval</del> <sup>deprecated, no real use</sup></li>
<li><del>vm.$interpolate</del> <sup>deprecated, no real use</sup></li>
<li><del>vm.$log</del> <sup>deprecated, use devtools</sup></li>
</ul>
<h5 dir="auto">events</h5>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> vm.$on</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> vm.$once</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> vm.$off</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> vm.$emit</li>
<li><del>vm.$dispatch</del> <sup>deprecated, use global event bus or Vuex. (see below)</sup></li>
<li><del>vm.$broadcast</del> <sup>deprecated, same as above</sup></li>
</ul>
<h5 dir="auto">DOM</h5>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> vm.$nextTick</li>
<li><del>vm.$appendTo</del> <sup>deprecated, just use native DOM API on vm.$el.</sup></li>
<li><del>vm.$before</del> <sup>deprecated</sup></li>
<li><del>vm.$after</del> <sup>deprecated</sup></li>
<li><del>vm.$remove</del> <sup>deprecated</sup></li>
</ul>
<h5 dir="auto">Lifecycle</h5>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> vm.$mount</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> vm.$destroy</li>
</ul>
<h3 dir="auto">Directives</h3>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> v-text</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> v-html <sup>but <code class="notranslate">{{{ }}}</code> shorthand has been deprecated</sup></li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> v-if</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> v-show</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> v-else</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> v-for
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> key (replacing track-by)</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> Object v-for</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> range v-for</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> argument order updates: <code class="notranslate">(value, index) in arr</code>, <code class="notranslate">(value, key, index) in obj</code></li>
<li><del><code class="notranslate">$index</code> and <code class="notranslate">$key</code></del> <sup>deprecated</sup></li>
</ul>
</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> v-on
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> modifiers</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> on child component</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> custom keyCodes (now avaiable via <code class="notranslate">Vue.config.keyCodes</code> instead of <code class="notranslate">Vue.directive('on').keyCodes</code>)</li>
</ul>
</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> v-bind
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> as prop</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> xlink</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> bind object</li>
</ul>
</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> v-bind:style
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> prefix sniffing</li>
</ul>
</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> v-bind:class</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> v-model
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> lazy (as modifier)</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> number (as modifier)</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> ignoring composition events</li>
<li><del>debounce</del> <sup>deprecated, use v-on:input + 3rd party debounce function</sup></li>
</ul>
</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> v-cloak</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> v-pre</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> v-once <sup>new</sup></li>
<li><del>v-ref</del> <sup>now just a special attribute as <code class="notranslate">ref</code></sup></li>
<li><del>v-el</del> <sup>deprecated (merged with ref)</sup></li>
</ul>
<h3 dir="auto">Special Components</h3>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> <code class="notranslate">&lt;component&gt;</code>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> :is</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> async components</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> inline-template</li>
</ul>
</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> <code class="notranslate">&lt;transition&gt;</code></li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> <code class="notranslate">&lt;transition-group&gt;</code></li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> <code class="notranslate">&lt;keep-alive&gt;</code></li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> <code class="notranslate">&lt;slot&gt;</code></li>
<li><del>partial</del> <sup>deprecated</sup></li>
</ul>
<h3 dir="auto">Special Attributes</h3>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> key</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> ref</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> slot</li>
</ul>
<h3 dir="auto">Server-side Rendering</h3>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> renderToString</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> renderToStream</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> client-side hydration</li>
</ul>
<h3 dir="auto">Other Breaking Changes</h3>
<h4 dir="auto"><code class="notranslate">v-for</code> iteration syntax change</h4>
<ul dir="auto">
<li>
<p dir="auto"><strong>Deprecating <code class="notranslate">$index</code> and <code class="notranslate">$key</code></strong></p>
<p dir="auto">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.</p>
</li>
<li>
<p dir="auto"><strong>New array syntax</strong></p>
<ul dir="auto">
<li><code class="notranslate">value in arr</code></li>
<li><code class="notranslate">(value, index) in arr</code> (switched order of arguments to be more consistent with JavaScript's <code class="notranslate">forEach</code> and <code class="notranslate">map</code>)</li>
</ul>
</li>
<li>
<p dir="auto"><strong>New object syntax</strong></p>
<ul dir="auto">
<li><code class="notranslate">value in obj</code></li>
<li><code class="notranslate">(value, key) in obj</code> (switched order of arguments, partly to be more consistent with many common object iterators, such as lodash's)</li>
<li><code class="notranslate">(value, key, index) in obj</code> (index will now be available in object iteration for visual purposes, such as table striping)</li>
</ul>
</li>
</ul>
<h4 dir="auto">Directive interface change</h4>
<p dir="auto">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.</p>
<p dir="auto">Directives no longer have instances - this means there's no more <code class="notranslate">this</code> inside directive hooks and <code class="notranslate">bind</code>, <code class="notranslate">update</code> and <code class="notranslate">unbind</code> now receives everything as arguments.</p>
<p dir="auto">Note the <code class="notranslate">binding</code> object is immutable, setting <code class="notranslate">binding.value</code> will have no effect, and properties added to it will not be persisted. You can persist directive state on <code class="notranslate">el</code> if you absolutely need to:</p>
<div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;div v-example:arg.modifier=&quot;a.b&quot;&gt;&lt;/div&gt;"><pre class="notranslate"><span class="pl-kos">&lt;</span><span class="pl-ent">div</span> <span class="pl-c1">v-example:arg.modifier</span>="<span class="pl-s">a.b</span>"<span class="pl-kos">&gt;</span><span class="pl-kos">&lt;/</span><span class="pl-ent">div</span><span class="pl-kos">&gt;</span></pre></div>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// example directive
export default {
  bind (el, binding, vnode) {
    // the binding object exposes value, oldValue, expression, arg and modifiers.
    binding.expression // &quot;a.b&quot;
    binding.arg // &quot;arg&quot;
    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) { ... }
}"><pre class="notranslate"><span class="pl-c">// example directive</span>
<span class="pl-k">export</span> <span class="pl-k">default</span> <span class="pl-kos">{</span>
  <span class="pl-en">bind</span> <span class="pl-kos">(</span><span class="pl-s1">el</span><span class="pl-kos">,</span> <span class="pl-s1">binding</span><span class="pl-kos">,</span> <span class="pl-s1">vnode</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-c">// the binding object exposes value, oldValue, expression, arg and modifiers.</span>
    <span class="pl-s1">binding</span><span class="pl-kos">.</span><span class="pl-c1">expression</span> <span class="pl-c">// "a.b"</span>
    <span class="pl-s1">binding</span><span class="pl-kos">.</span><span class="pl-c1">arg</span> <span class="pl-c">// "arg"</span>
    <span class="pl-s1">binding</span><span class="pl-kos">.</span><span class="pl-c1">modifiers</span> <span class="pl-c">// { modifier: true }</span>
    <span class="pl-c">// the context Vue instance can be accessed as vnode.context.</span>
  <span class="pl-kos">}</span><span class="pl-kos">,</span>

  <span class="pl-c">// update has a few changes, see below</span>
  <span class="pl-en">update</span> <span class="pl-kos">(</span><span class="pl-s1">el</span><span class="pl-kos">,</span> <span class="pl-s1">binding</span><span class="pl-kos">,</span> <span class="pl-s1">vnode</span><span class="pl-kos">,</span> <span class="pl-s1">oldVnode</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> ... <span class="pl-kos">}</span><span class="pl-kos">,</span>

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

  <span class="pl-en">unbind</span> <span class="pl-kos">(</span><span class="pl-s1">el</span><span class="pl-kos">,</span> <span class="pl-s1">binding</span><span class="pl-kos">,</span> <span class="pl-s1">vnode</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> ... <span class="pl-kos">}</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">You can use destructuring if you only care about the value:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="export default {
  bind (el, { value }) {
    // ...
  }
}"><pre class="notranslate"><span class="pl-k">export</span> <span class="pl-k">default</span> <span class="pl-kos">{</span>
  <span class="pl-en">bind</span> <span class="pl-kos">(</span><span class="pl-s1">el</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> value <span class="pl-kos">}</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-c">// ...</span>
  <span class="pl-kos">}</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">In addition, the <code class="notranslate">update</code> hook has a few changes:</p>
<ol dir="auto">
<li>It no longer gets called automatically after <code class="notranslate">bind</code>.</li>
<li>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 <code class="notranslate">binding.value === binding.oldValue</code> 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.</li>
</ol>
<p dir="auto"><code class="notranslate">elementDirective</code>, directive params and directive options such as <code class="notranslate">acceptStatement</code>, <code class="notranslate">deep</code> etc. are all deprecated.</p>
<h4 dir="auto">Filter Usage and Syntax Change</h4>
<p dir="auto">In Vue 2.0, there are several changes to the filter system:</p>
<ol dir="auto">
<li>
<p dir="auto">Filters can now only be used inside text interpolations (<code class="notranslate">{{}}</code> tags). In the past we've found using filters with directives such as <code class="notranslate">v-model</code>, <code class="notranslate">v-on</code> etc. led to more complexity than convenience, and for list filtering on <code class="notranslate">v-for</code> it is more appropriate to move that logic into JavaScript as computed properties.</p>
</li>
<li>
<p dir="auto">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. <a href="http://momentjs.com/" rel="nofollow">moment.js</a> for formatting dates and <a href="http://openexchangerates.github.io/accounting.js/" rel="nofollow">accounting.js</a> for formatting financial currencies. You are also welcome to create your own filter pack and share it with the community!</p>
</li>
<li>
<p dir="auto">The filter syntax has changed to be more inline with JavaScript function invocation, instead of taking space-delimited arguments:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="{{ date | formatDate('YY-MM-DD') }}"><pre class="notranslate"><code class="notranslate">{{ date | formatDate('YY-MM-DD') }}
</code></pre></div>
</li>
</ol>
<h4 dir="auto">Transition System</h4>
<p dir="auto"><strong>Transition CSS class changes:</strong></p>
<p dir="auto">The always-on <code class="notranslate">v-transition</code> class is no longer added and Vue now uses the same classes Angular and React CSSTransitionGroup does:</p>
<ul dir="auto">
<li>
<p dir="auto"><code class="notranslate">v-enter</code>: applied before element is inserted, remove after 1 tick. (starting state for enter)</p>
</li>
<li>
<p dir="auto"><code class="notranslate">v-enter-active</code>: applied before element is inserted, removed when transition/animation finishes. (active + ending state for enter)</p>
</li>
<li>
<p dir="auto"><code class="notranslate">v-leave</code>: applied right when the leave transition is triggered, remove after 1 tick (starting state for leave)</p>
</li>
<li>
<p dir="auto"><code class="notranslate">v-leave-active</code>: applied right when the leave transition is triggered, removed when the transition/animation finishes. (active + ending state for leave)</p>
<p dir="auto"><code class="notranslate">v-enter-active</code> and <code class="notranslate">v-leave-active</code> gives you the ability to specify different easing curves for enter/leave transitions. In most cases, upgrading means simply replacing your current <code class="notranslate">v-leave</code>with <code class="notranslate">v-leave-active</code>. (For CSS animations, use <code class="notranslate">v-enter-active</code> + <code class="notranslate">v-leave-active</code>)</p>
</li>
</ul>
<h4 dir="auto">Transition API Change</h4>
<ul dir="auto">
<li>
<p dir="auto"><strong>The <code class="notranslate">&lt;transition&gt;</code> component</strong></p>
<p dir="auto">All single-element transition effects are now applied by wrapping the target element/component with the <code class="notranslate">&lt;transition&gt;</code> 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.</p>
<p dir="auto">The simplest usage example:</p>
<div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;transition&gt;
  &lt;div v-if=&quot;ok&quot;&gt;toggled content&lt;/div&gt;
&lt;/transition&gt;"><pre class="notranslate"><span class="pl-kos">&lt;</span><span class="pl-ent">transition</span><span class="pl-kos">&gt;</span>
  <span class="pl-kos">&lt;</span><span class="pl-ent">div</span> <span class="pl-c1">v-if</span>="<span class="pl-s">ok</span>"<span class="pl-kos">&gt;</span>toggled content<span class="pl-kos">&lt;/</span><span class="pl-ent">div</span><span class="pl-kos">&gt;</span>
<span class="pl-kos">&lt;/</span><span class="pl-ent">transition</span><span class="pl-kos">&gt;</span></pre></div>
<p dir="auto">The component defines a number of props and events that maps directly to the old transition definition options:</p>
<p dir="auto"><strong>Props</strong></p>
<ul dir="auto">
<li>
<p dir="auto"><strong>name: String</strong></p>
<p dir="auto">Used to automatically generate transition CSS class names. e.g. <code class="notranslate">name: 'fade'</code> will auto expand to <code class="notranslate">.fade-enter</code>, <code class="notranslate">.fade-enter-active</code>, etc. Defaults to <code class="notranslate">"v"</code>.</p>
</li>
<li>
<p dir="auto"><strong>appear: Boolean</strong></p>
<p dir="auto">Whether to apply transition on initial render. Defaults to <code class="notranslate">false</code>.</p>
</li>
<li>
<p dir="auto"><strong>css: Boolean</strong></p>
<p dir="auto">Whether to apply CSS transition classes. Defaults to <code class="notranslate">true</code>. If set to <code class="notranslate">false</code>, will only trigger JavaScript hooks registered via component events.</p>
</li>
<li>
<p dir="auto"><strong>type: String</strong></p>
<p dir="auto">Specify the type of transition events to wait for to determine transition end timing. Available values are <code class="notranslate">"transition"</code> and <code class="notranslate">"animation"</code>. By default, it will automatically detect the type that has a longer duration.</p>
</li>
<li>
<p dir="auto"><strong>mode: String</strong></p>
<p dir="auto">Controls the timing sequence of leaving/entering transitions. Available modes are <code class="notranslate">"out-in"</code> and <code class="notranslate">"in-out"</code>; defaults to simultaneous.</p>
</li>
<li>
<p dir="auto"><strong>enterClass, leaveClass, enterActiveClass, leaveActiveClass, appearClass, appearActiveClass: String</strong></p>
<p dir="auto">Individually configure transition CSS classes.</p>
</li>
</ul>
<p dir="auto">Example applying transition to dynamic components:</p>
<div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;transition name=&quot;fade&quot; mode=&quot;out-in&quot; appear&gt;
  &lt;component :is=&quot;view&quot;&gt;&lt;/component&gt;
&lt;/transition&gt;"><pre class="notranslate"><span class="pl-kos">&lt;</span><span class="pl-ent">transition</span> <span class="pl-c1">name</span>="<span class="pl-s">fade</span>" <span class="pl-c1">mode</span>="<span class="pl-s">out-in</span>" <span class="pl-c1">appear</span><span class="pl-kos">&gt;</span>
  <span class="pl-kos">&lt;</span><span class="pl-ent">component</span> <span class="pl-c1">:is</span>="<span class="pl-s">view</span>"<span class="pl-kos">&gt;</span><span class="pl-kos">&lt;/</span><span class="pl-ent">component</span><span class="pl-kos">&gt;</span>
<span class="pl-kos">&lt;/</span><span class="pl-ent">transition</span><span class="pl-kos">&gt;</span></pre></div>
<p dir="auto"><strong>Events</strong></p>
<p dir="auto">Corresponds to the JavaScript hooks available in 1.x API.</p>
<ul dir="auto">
<li><strong>before-enter</strong></li>
<li><strong>enter</strong></li>
<li><strong>after-enter</strong></li>
<li><strong>before-leave</strong></li>
<li><strong>leave</strong></li>
<li><strong>after-leave</strong></li>
<li><strong>before-appear</strong></li>
<li><strong>appear</strong></li>
<li><strong>after-appear</strong></li>
</ul>
<p dir="auto">Example:</p>
<div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;transition @after-enter=&quot;transitionComplete&quot;&gt;
  &lt;div v-show=&quot;ok&quot;&gt;toggled content&lt;/div&gt;
&lt;/transition&gt;"><pre class="notranslate"><span class="pl-kos">&lt;</span><span class="pl-ent">transition</span> <span class="pl-c1">@after-enter</span>="<span class="pl-s">transitionComplete</span>"<span class="pl-kos">&gt;</span>
  <span class="pl-kos">&lt;</span><span class="pl-ent">div</span> <span class="pl-c1">v-show</span>="<span class="pl-s">ok</span>"<span class="pl-kos">&gt;</span>toggled content<span class="pl-kos">&lt;/</span><span class="pl-ent">div</span><span class="pl-kos">&gt;</span>
<span class="pl-kos">&lt;/</span><span class="pl-ent">transition</span><span class="pl-kos">&gt;</span></pre></div>
<p dir="auto">When the entering transition completes, the component's <code class="notranslate">transitionComplete</code> method will be called with the transitioned DOM element as the argument.</p>
<p dir="auto">Some notes:</p>
<ul dir="auto">
<li><code class="notranslate">leave-cancelled</code> is no longer available for insertion/removals. Once a leave transition starts, it cannot be cancelled. It is, however, still available for <code class="notranslate">v-show</code> transitions.</li>
<li>Similar to 1.0, for <code class="notranslate">enter</code> and <code class="notranslate">leave</code> hooks, the presence of <code class="notranslate">cb</code> as the second argument indicates the user wants explicit control of the ending timing of the transition.</li>
</ul>
</li>
<li>
<p dir="auto"><strong>The <code class="notranslate">&lt;transition-group&gt;</code> component</strong></p>
<p dir="auto">All multi-element transition effects are now applied by wrapping the elements with the <code class="notranslate">&lt;transition-group&gt;</code> built-in component. It exposes the same props and events as <code class="notranslate">&lt;transition&gt;</code> does. The difference being that:</p>
<ol dir="auto">
<li>Unlike <code class="notranslate">&lt;transition&gt;</code>, <code class="notranslate">&lt;transition-group&gt;</code> renders a real DOM element. By default it renders a <code class="notranslate">&lt;span&gt;</code>, and you can configure what element is should render via the <code class="notranslate">tag</code> prop. You can also use it with the <code class="notranslate">is</code> attribute, e.g. <code class="notranslate">&lt;ul is="transition-group"&gt;</code>.</li>
<li><code class="notranslate">&lt;transition-group&gt;</code> does not support the <code class="notranslate">mode</code> prop.</li>
<li>Every child in a <code class="notranslate">&lt;transition-group&gt;</code> must be <strong>uniquely keyed</strong>.</li>
</ol>
<p dir="auto">Example:</p>
<div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;transition-group tag=&quot;ul&quot; name=&quot;slide&quot;&gt;
  &lt;li v-for=&quot;item in items&quot; :key=&quot;item.id&quot;&gt;
    {{ item.text }}
  &lt;/li&gt;
&lt;/transition-group&gt;"><pre class="notranslate"><span class="pl-kos">&lt;</span><span class="pl-ent">transition-group</span> <span class="pl-c1">tag</span>="<span class="pl-s">ul</span>" <span class="pl-c1">name</span>="<span class="pl-s">slide</span>"<span class="pl-kos">&gt;</span>
  <span class="pl-kos">&lt;</span><span class="pl-ent">li</span> <span class="pl-c1">v-for</span>="<span class="pl-s">item in items</span>" <span class="pl-c1">:key</span>="<span class="pl-s">item.id</span>"<span class="pl-kos">&gt;</span>
    {{ item.text }}
  <span class="pl-kos">&lt;/</span><span class="pl-ent">li</span><span class="pl-kos">&gt;</span>
<span class="pl-kos">&lt;/</span><span class="pl-ent">transition-group</span><span class="pl-kos">&gt;</span></pre></div>
<p dir="auto"><strong>Moving Transitions</strong></p>
<p dir="auto"><code class="notranslate">&lt;transition-group&gt;</code> supports <strong>moving transitions</strong> 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 <code class="notranslate">name</code> prop or configured with the <code class="notranslate">moveClass</code> prop). If the CSS <code class="notranslate">transform</code> property is "transition-able" when the moving class is applied, the element will be smoothly animated to its destination using the <a href="https://aerotwist.com/blog/flip-your-animations/" rel="nofollow">FLIP technique</a>.</p>
<p dir="auto">See a <a href="https://jsfiddle.net/yyx990803/yfpLvjxx/" rel="nofollow">live demo</a> here.</p>
</li>
<li>
<p dir="auto"><strong>Creating Reusable Transitions</strong></p>
<p dir="auto">Now that transitions are applied via components, they are no longer considered an asset type, so the global <code class="notranslate">Vue.transition()</code> method and the <code class="notranslate">transition</code> 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):</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="Vue.component('fade', {
  functional: true,
  render (createElement, { children }) {
    const data = {
      props: {
        name: 'fade'
      },
      on: {
        beforeEnter () { /* ... */ }, // &lt;-- Note hooks use camelCase in JavaScript (same as 1.x)
        afterEnter () { /* ... */ }
      }
    }
    return createElement('transition', data, children)
  }
})"><pre class="notranslate"><span class="pl-v">Vue</span><span class="pl-kos">.</span><span class="pl-en">component</span><span class="pl-kos">(</span><span class="pl-s">'fade'</span><span class="pl-kos">,</span> <span class="pl-kos">{</span>
  <span class="pl-c1">functional</span>: <span class="pl-c1">true</span><span class="pl-kos">,</span>
  <span class="pl-en">render</span> <span class="pl-kos">(</span><span class="pl-s1">createElement</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> children <span class="pl-kos">}</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-k">const</span> <span class="pl-s1">data</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span>
      <span class="pl-c1">props</span>: <span class="pl-kos">{</span>
        <span class="pl-c1">name</span>: <span class="pl-s">'fade'</span>
      <span class="pl-kos">}</span><span class="pl-kos">,</span>
      <span class="pl-c1">on</span>: <span class="pl-kos">{</span>
        <span class="pl-en">beforeEnter</span> <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> <span class="pl-c">/* ... */</span> <span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-c">// &lt;-- Note hooks use camelCase in JavaScript (same as 1.x)</span>
        <span class="pl-en">afterEnter</span> <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> <span class="pl-c">/* ... */</span> <span class="pl-kos">}</span>
      <span class="pl-kos">}</span>
    <span class="pl-kos">}</span>
    <span class="pl-k">return</span> <span class="pl-s1">createElement</span><span class="pl-kos">(</span><span class="pl-s">'transition'</span><span class="pl-kos">,</span> <span class="pl-s1">data</span><span class="pl-kos">,</span> <span class="pl-s1">children</span><span class="pl-kos">)</span>
  <span class="pl-kos">}</span>
<span class="pl-kos">}</span><span class="pl-kos">)</span></pre></div>
<p dir="auto">You can then use it like this:</p>
<div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;fade&gt;
  &lt;div v-if=&quot;ok&quot;&gt;toggled content&lt;/div&gt;
&lt;/fade&gt;"><pre class="notranslate"><span class="pl-kos">&lt;</span><span class="pl-ent">fade</span><span class="pl-kos">&gt;</span>
  <span class="pl-kos">&lt;</span><span class="pl-ent">div</span> <span class="pl-c1">v-if</span>="<span class="pl-s">ok</span>"<span class="pl-kos">&gt;</span>toggled content<span class="pl-kos">&lt;/</span><span class="pl-ent">div</span><span class="pl-kos">&gt;</span>
<span class="pl-kos">&lt;/</span><span class="pl-ent">fade</span><span class="pl-kos">&gt;</span></pre></div>
</li>
</ul>
<h4 dir="auto">v-model changes</h4>
<ul dir="auto">
<li>
<p dir="auto">The <code class="notranslate">lazy</code> and <code class="notranslate">number</code> params are now modifiers:</p>
<div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;input v-model.lazy=&quot;text&quot;&gt;"><pre class="notranslate"><span class="pl-kos">&lt;</span><span class="pl-ent">input</span> <span class="pl-c1">v-model.lazy</span>="<span class="pl-s">text</span>"<span class="pl-kos">&gt;</span></pre></div>
</li>
<li>
<p dir="auto">New modifier: <code class="notranslate">.trim</code> - trims the input, as the name suggests.</p>
</li>
<li>
<p dir="auto">The <code class="notranslate">debounce</code> param has been deprecated. (See upgrade tip at bottom)</p>
</li>
<li>
<p dir="auto"><code class="notranslate">v-model</code> no longer cares about initial inline <code class="notranslate">value</code>. 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:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="data: {
  val: 1
}"><pre class="notranslate">data: <span class="pl-kos">{</span>
  <span class="pl-c1">val</span>: <span class="pl-c1">1</span>
<span class="pl-kos">}</span></pre></div>
<div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;input v-model=&quot;val&quot; value=&quot;2&quot;&gt;"><pre class="notranslate"><span class="pl-kos">&lt;</span><span class="pl-ent">input</span> <span class="pl-c1">v-model</span>="<span class="pl-s">val</span>" <span class="pl-c1">value</span>="<span class="pl-s">2</span>"<span class="pl-kos">&gt;</span></pre></div>
<p dir="auto">Same goes for <code class="notranslate">&lt;textarea&gt;</code> with existing content. So instead of:</p>
<div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;textarea v-model=&quot;val&quot;&gt;hello world&lt;/textarea&gt;"><pre class="notranslate"><span class="pl-kos">&lt;</span><span class="pl-ent">textarea</span> <span class="pl-c1">v-model</span>="<span class="pl-s">val</span>"<span class="pl-kos">&gt;</span>hello world<span class="pl-kos">&lt;/</span><span class="pl-ent">textarea</span><span class="pl-kos">&gt;</span></pre></div>
<p dir="auto">Do:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="data () {
  return {
    val: 'hello world'
  }
}"><pre class="notranslate"><span class="pl-en">data</span> <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
  <span class="pl-k">return</span> <span class="pl-kos">{</span>
    <span class="pl-c1">val</span>: <span class="pl-s">'hello world'</span>
  <span class="pl-kos">}</span>
<span class="pl-kos">}</span></pre></div>
<div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;textarea v-model=&quot;val&quot;&gt;&lt;/textarea&gt;"><pre class="notranslate"><span class="pl-kos">&lt;</span><span class="pl-ent">textarea</span> <span class="pl-c1">v-model</span>="<span class="pl-s">val</span>"<span class="pl-kos">&gt;</span><span class="pl-kos">&lt;/</span><span class="pl-ent">textarea</span><span class="pl-kos">&gt;</span></pre></div>
<p dir="auto">The main idea is that the JS side should be considered the source of truth, not your templates.</p>
</li>
<li>
<p dir="auto"><code class="notranslate">v-model</code> no longer works when used on a <code class="notranslate">v-for</code> iterated primitive value:</p>
<div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;input v-for=&quot;str in strings&quot; v-model=&quot;str&quot;&gt;"><pre class="notranslate"><span class="pl-kos">&lt;</span><span class="pl-ent">input</span> <span class="pl-c1">v-for</span>="<span class="pl-s">str in strings</span>" <span class="pl-c1">v-model</span>="<span class="pl-s">str</span>"<span class="pl-kos">&gt;</span></pre></div>
<p dir="auto">This doesn't work because it's the equivalent of this in JavaScript:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="strings.map(function (str) {
  return createElement('input', ...)
})"><pre class="notranslate"><span class="pl-s1">strings</span><span class="pl-kos">.</span><span class="pl-en">map</span><span class="pl-kos">(</span><span class="pl-k">function</span> <span class="pl-kos">(</span><span class="pl-s1">str</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
  <span class="pl-k">return</span> <span class="pl-en">createElement</span><span class="pl-kos">(</span><span class="pl-s">'input'</span><span class="pl-kos">,</span> ...<span class="pl-kos">)</span>
<span class="pl-kos">}</span><span class="pl-kos">)</span></pre></div>
<p dir="auto">As you can see, setting <code class="notranslate">str</code> 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 <code class="notranslate">v-model</code> can update the field on the object:</p>
<div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;input v-for=&quot;obj in objects&quot; v-model=&quot;obj.str&quot;&gt;"><pre class="notranslate"><span class="pl-kos">&lt;</span><span class="pl-ent">input</span> <span class="pl-c1">v-for</span>="<span class="pl-s">obj in objects</span>" <span class="pl-c1">v-model</span>="<span class="pl-s">obj.str</span>"<span class="pl-kos">&gt;</span></pre></div>
</li>
</ul>
<h4 dir="auto">Props Behavior</h4>
<ul dir="auto">
<li><code class="notranslate">.once</code> and <code class="notranslate">.sync</code> 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.</li>
<li>Mutating a prop locally is now considered an anti-pattern, e.g. declaring a prop <code class="notranslate">a</code> and then set <code class="notranslate">this.a = someOtherValue</code> 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 <strong>treat props as immutable</strong>. Most use cases of mutating a prop can be replaced by either a data property or a computed property.</li>
</ul>
<h4 dir="auto">keep-alive</h4>
<p dir="auto"><code class="notranslate">keep-alive</code> is no longer a special attribute: it is now a wrapper component, similar to <code class="notranslate">&lt;transition&gt;</code>:</p>
<div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="  &lt;keep-alive&gt;
    &lt;component :is=&quot;view&quot;&gt;&lt;/component&gt;
  &lt;/keep-alive&gt;"><pre class="notranslate">  <span class="pl-kos">&lt;</span><span class="pl-ent">keep-alive</span><span class="pl-kos">&gt;</span>
    <span class="pl-kos">&lt;</span><span class="pl-ent">component</span> <span class="pl-c1">:is</span>="<span class="pl-s">view</span>"<span class="pl-kos">&gt;</span><span class="pl-kos">&lt;/</span><span class="pl-ent">component</span><span class="pl-kos">&gt;</span>
  <span class="pl-kos">&lt;/</span><span class="pl-ent">keep-alive</span><span class="pl-kos">&gt;</span></pre></div>
<p dir="auto">This makes it possible to use <code class="notranslate">keep-alive</code> on multiple conditional children (note the children should eventually evaluate to a single child - any child other than the first one will be ignored):</p>
<div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="  &lt;keep-alive&gt;
    &lt;comp-a v-if=&quot;a &gt; 1&quot;&gt;&lt;/comp-a&gt;
    &lt;comp-b v-else&gt;&lt;/comp-b&gt;
  &lt;/keep-alive&gt;"><pre class="notranslate">  <span class="pl-kos">&lt;</span><span class="pl-ent">keep-alive</span><span class="pl-kos">&gt;</span>
    <span class="pl-kos">&lt;</span><span class="pl-ent">comp-a</span> <span class="pl-c1">v-if</span>="<span class="pl-s">a &gt; 1</span>"<span class="pl-kos">&gt;</span><span class="pl-kos">&lt;/</span><span class="pl-ent">comp-a</span><span class="pl-kos">&gt;</span>
    <span class="pl-kos">&lt;</span><span class="pl-ent">comp-b</span> <span class="pl-c1">v-else</span><span class="pl-kos">&gt;</span><span class="pl-kos">&lt;/</span><span class="pl-ent">comp-b</span><span class="pl-kos">&gt;</span>
  <span class="pl-kos">&lt;/</span><span class="pl-ent">keep-alive</span><span class="pl-kos">&gt;</span></pre></div>
<p dir="auto">When used together with <code class="notranslate">&lt;transition&gt;</code>, make sure to nest it inside:</p>
<div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="  &lt;transition&gt;
    &lt;keep-alive&gt;
      &lt;component :is=&quot;view&quot;&gt;&lt;/component&gt;
    &lt;/keep-alive&gt;
  &lt;/transition&gt;"><pre class="notranslate">  <span class="pl-kos">&lt;</span><span class="pl-ent">transition</span><span class="pl-kos">&gt;</span>
    <span class="pl-kos">&lt;</span><span class="pl-ent">keep-alive</span><span class="pl-kos">&gt;</span>
      <span class="pl-kos">&lt;</span><span class="pl-ent">component</span> <span class="pl-c1">:is</span>="<span class="pl-s">view</span>"<span class="pl-kos">&gt;</span><span class="pl-kos">&lt;/</span><span class="pl-ent">component</span><span class="pl-kos">&gt;</span>
    <span class="pl-kos">&lt;/</span><span class="pl-ent">keep-alive</span><span class="pl-kos">&gt;</span>
  <span class="pl-kos">&lt;/</span><span class="pl-ent">transition</span><span class="pl-kos">&gt;</span></pre></div>
<h4 dir="auto">Slots</h4>
<ul dir="auto">
<li>It is no longer supported to have duplicate <code class="notranslate">&lt;slot&gt;</code>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.</li>
<li>Content inserted via named <code class="notranslate">&lt;slot&gt;</code> no longer preserves the <code class="notranslate">slot</code> attribute. Use a wrapper element to style them, or, for advanced use cases, modify the inserted content programmatically using render functions.</li>
</ul>
<h4 dir="auto">Refs</h4>
<ul dir="auto">
<li>
<p dir="auto"><code class="notranslate">v-ref</code> is now no longer a directive: it is now a special attribute similar to <code class="notranslate">key</code> and <code class="notranslate">transition</code>:</p>
<div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;!-- before --&gt;
&lt;comp v-ref:foo&gt;&lt;/comp&gt;

&lt;!-- after --&gt;
&lt;comp ref=&quot;foo&quot;&gt;&lt;/comp&gt;"><pre class="notranslate"><span class="pl-c">&lt;!-- before --&gt;</span>
<span class="pl-kos">&lt;</span><span class="pl-ent">comp</span> <span class="pl-c1">v-ref:foo</span><span class="pl-kos">&gt;</span><span class="pl-kos">&lt;/</span><span class="pl-ent">comp</span><span class="pl-kos">&gt;</span>

<span class="pl-c">&lt;!-- after --&gt;</span>
<span class="pl-kos">&lt;</span><span class="pl-ent">comp</span> <span class="pl-c1">ref</span>="<span class="pl-s">foo</span>"<span class="pl-kos">&gt;</span><span class="pl-kos">&lt;/</span><span class="pl-ent">comp</span><span class="pl-kos">&gt;</span></pre></div>
<p dir="auto">Dynamic ref bindings are now also supported:</p>
<div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;comp :ref=&quot;dynamicRef&quot;&gt;&lt;/comp&gt;"><pre class="notranslate"><span class="pl-kos">&lt;</span><span class="pl-ent">comp</span> <span class="pl-c1">:ref</span>="<span class="pl-s">dynamicRef</span>"<span class="pl-kos">&gt;</span><span class="pl-kos">&lt;/</span><span class="pl-ent">comp</span><span class="pl-kos">&gt;</span></pre></div>
</li>
<li>
<p dir="auto"><code class="notranslate">vm.$els</code> and <code class="notranslate">vm.$refs</code> 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.</p>
</li>
<li>
<p dir="auto"><code class="notranslate">vm.$refs</code> are no longer reactive, because they are registered/updated during the render process itself. Making them reactive would require duplicate renders for every change.</p>
<p dir="auto">On the other hand, <code class="notranslate">$refs</code> are designed primarily for programmatic access in JavaScript - it is not recommended to rely on <code class="notranslate">$refs</code> in templates because it entails referring to state that does not belong to the instance itself.</p>
</li>
</ul>
<h4 dir="auto">Misc</h4>
<ul dir="auto">
<li>
<p dir="auto"><code class="notranslate">track-by</code> has been replaced with <code class="notranslate">key</code>. It now follows the same rule for binding an attribute: without <code class="notranslate">v-bind:</code> or <code class="notranslate">:</code> prefix, it is treated as a <strong>literal string</strong>. In most cases you'd want to use a dynamic binding, which expects a full expression instead of a string key. For example:</p>
<div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;!-- 1.x --&gt;
&lt;div v-for=&quot;item in items&quot; track-by=&quot;id&quot;&gt;

&lt;!-- 2.0 --&gt;
&lt;div v-for=&quot;item in items&quot; :key=&quot;item.id&quot;&gt;"><pre class="notranslate"><span class="pl-c">&lt;!-- 1.x --&gt;</span>
<span class="pl-kos">&lt;</span><span class="pl-ent">div</span> <span class="pl-c1">v-for</span>="<span class="pl-s">item in items</span>" <span class="pl-c1">track-by</span>="<span class="pl-s">id</span>"<span class="pl-kos">&gt;</span>

<span class="pl-c">&lt;!-- 2.0 --&gt;</span>
<span class="pl-kos">&lt;</span><span class="pl-ent">div</span> <span class="pl-c1">v-for</span>="<span class="pl-s">item in items</span>" <span class="pl-c1">:key</span>="<span class="pl-s">item.id</span>"<span class="pl-kos">&gt;</span></pre></div>
</li>
<li>
<p dir="auto">Interpolation inside attributes are deprecated:</p>
<div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;!-- 1.x --&gt;
&lt;div id=&quot;{{ id }}&quot;&gt;

&lt;!-- 2.0 --&gt;
&lt;div :id=&quot;id&quot;&gt;"><pre class="notranslate"><span class="pl-c">&lt;!-- 1.x --&gt;</span>
<span class="pl-kos">&lt;</span><span class="pl-ent">div</span> <span class="pl-c1">id</span>="<span class="pl-s">{{ id }}</span>"<span class="pl-kos">&gt;</span>

<span class="pl-c">&lt;!-- 2.0 --&gt;</span>
<span class="pl-kos">&lt;</span><span class="pl-ent">div</span> <span class="pl-c1">:id</span>="<span class="pl-s">id</span>"<span class="pl-kos">&gt;</span></pre></div>
</li>
<li>
<p dir="auto">Attribute binding behavior change: only <code class="notranslate">null</code>, <code class="notranslate">undefined</code> and <code class="notranslate">false</code> are considered falsy when binding attributes. This means <code class="notranslate">0</code> and empty strings will render as-is. For enumerated attributes. This means <code class="notranslate">:draggable="''"</code> will render as <code class="notranslate">draggable="true"</code>.</p>
<p dir="auto">Also, for enumerated attributes, in addition to the falsy values above, the string value of "false" will also render as attr="false".</p>
</li>
<li>
<p dir="auto">When used on a custom component, <code class="notranslate">v-on</code> now only listens to custom events $emitted by that component. (no longer listens to DOM events)</p>
</li>
<li>
<p dir="auto"><code class="notranslate">v-else</code> no longer works with <code class="notranslate">v-show</code> - just use negation expression.</p>
</li>
<li>
<p dir="auto">One time bindings (<code class="notranslate">{{* foo }}</code>) deprecated - use <code class="notranslate">v-once</code> instead.</p>
</li>
<li>
<p dir="auto">Array.prototype.$set/$remove deprecated (use Vue.set or Array.prototype.splice instead)</p>
</li>
<li>
<p dir="auto"><code class="notranslate">:style</code> no longer supports inline <code class="notranslate">!important</code></p>
</li>
<li>
<p dir="auto">root instance can no longer use template props (use <code class="notranslate">propsData</code> instead)</p>
</li>
<li>
<p dir="auto">The <code class="notranslate">el</code> option can no longer be used in <code class="notranslate">Vue.extend</code>. It can now only be used as an instance creation option.</p>
</li>
<li>
<p dir="auto"><code class="notranslate">Vue.set</code> and <code class="notranslate">Vue.delete</code> cannot work on Vue instances. It is now mandatory to properly declare all top-level reactive properties in the <code class="notranslate">data</code> option.</p>
</li>
<li>
<p dir="auto">It is now also prohibited to replace a component instance's root <code class="notranslate">$data</code>. This prevents some edge cases in the reactivity system and makes the component state more predictable (especially with type-checking systems).</p>
</li>
<li>
<p dir="auto">User watchers created via <code class="notranslate">vm.$watch</code> 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.</p>
<p dir="auto">To do something with the DOM after component updates, just use the updated lifecycle hook.</p>
</li>
</ul>
<h3 dir="auto">Upgrade Tips</h3>
<h4 dir="auto">How to Deal with Deprecation of <code class="notranslate">$dispatch</code> and <code class="notranslate">$broadcast</code>?</h4>
<p dir="auto">The reason that we are deprecating <code class="notranslate">$dispatch</code> and <code class="notranslate">$broadcast</code> 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). <code class="notranslate">$dispatch</code> and <code class="notranslate">$broadcast</code> also do not solve the communication between sibling components. Instead, you can use a pattern similar to the <a href="https://nodejs.org/api/events.html#events_class_eventemitter" rel="nofollow">EventEmitter in Node.js</a>: 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:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="var bus = new Vue()"><pre class="notranslate"><span class="pl-k">var</span> <span class="pl-s1">bus</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-v">Vue</span><span class="pl-kos">(</span><span class="pl-kos">)</span></pre></div>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// in component A's method
bus.$emit('id-selected', 1)"><pre class="notranslate"><span class="pl-c">// in component A's method</span>
<span class="pl-s1">bus</span><span class="pl-kos">.</span><span class="pl-en">$emit</span><span class="pl-kos">(</span><span class="pl-s">'id-selected'</span><span class="pl-kos">,</span> <span class="pl-c1">1</span><span class="pl-kos">)</span></pre></div>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// in component B's created hook
bus.$on('id-selected', this.someMethod)"><pre class="notranslate"><span class="pl-c">// in component B's created hook</span>
<span class="pl-s1">bus</span><span class="pl-kos">.</span><span class="pl-en">$on</span><span class="pl-kos">(</span><span class="pl-s">'id-selected'</span><span class="pl-kos">,</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">someMethod</span><span class="pl-kos">)</span></pre></div>
<p dir="auto">And don't forget to use $off to unbind the event.</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// in component B's destroyed hook
bus.$off('id-selected', this.someMethod)"><pre class="notranslate"><span class="pl-c">// in component B's destroyed hook</span>
<span class="pl-s1">bus</span><span class="pl-kos">.</span><span class="pl-en">$off</span><span class="pl-kos">(</span><span class="pl-s">'id-selected'</span><span class="pl-kos">,</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">someMethod</span><span class="pl-kos">)</span></pre></div>
<p dir="auto">This pattern can serve as a replacement for <code class="notranslate">$dispatch</code> and <code class="notranslate">$broadcast</code> in simple scenarios. But for more complex cases, it is recommended to introduce a dedicated state management layer using <a href="https://github.com/vuejs/vuex">Vuex</a>.</p>
<h4 dir="auto">How to Deal with the Deprecation of Array Filters?</h4>
<p dir="auto">For list filtering with <code class="notranslate">v-for</code> - 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 <a href="https://github.com/vuejs/vue/blob/next/examples/grid/grid.js#L21-L41">updated data grid example</a>). 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.</p>
<p dir="auto">Also see <a href="https://github.com/vuejs/vue/issues/2756" data-hovercard-type="issue" data-hovercard-url="/vuejs/vue/issues/2756/hovercard">this discussion thread</a>.</p>
<h4 dir="auto">How to Deal with the Deprecation of <code class="notranslate">debounce</code> for <code class="notranslate">v-model</code>?</h4>
<p dir="auto">Debouncing is used to limit how often we execute Ajax requests and other expensive operations. Vue's <code class="notranslate">debounce</code> attribute parameter for <code class="notranslate">v-model</code> makes this easy, but it also debounces <em>state updates</em> rather than the expensive operations themselves, which comes with limitations.</p>
<p dir="auto">These limitations become apparent when designing a <a href="https://jsbin.com/zefawu/3/edit?html,output" rel="nofollow">search indicator</a>. Take a look at that example. Using the <code class="notranslate">debounce</code> 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 <em>only</em> the operation we want to limit.</p>
<p dir="auto">There will be other times when debouncing isn't <em>quite</em> 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 <a href="https://jsbin.com/zefawu/5/edit?html,output" rel="nofollow">throttling function</a>. Now since you're already using a utility library like lodash for <code class="notranslate">debounce</code>, refactoring to use <code class="notranslate">throttle</code> instead takes only a few seconds!</p>