About the Release"The fate of destruction is also the joy of rebirth." - SEELE
Please read the blog post.
Known Issuesv-for="(index, val) in items"
syntax doesn't update the index
properly. This has been fixed in dev
branch and will be out in 1.0.1.This is the biggest change: directive syntax has been overhauled. No more multiple clauses; arguments are now placed inside the attribute name. The attribute value should now always be a single JavaScript expression followed by filters.
In the past, asset resolution (components, directives, filters...) has implicit fallback: if an asset is not found in the current component, Vue.js will recursively look for it in its parent, its parent's parent... and so on. This allows you to, say, define a component in the root instance and use it in any child component. It is convenient, however we've found that in large projects it results to implicit coupling between a child component and its ancestors. It also hurts maintainability - when you are looking at a child component in isolation, it's hard to identify where an asset comes from because it could've been provided by any ancestor up the component chain.
Therefore, in 1.0 all asset resolution is "strict": an asset should either be defined on the current component, or defined as a true global asset (using one of the global Vue.xxx
asset registration methods).
v-repeat
has been replaced by v-for
, which is much faster, but comes with a few differences:
v-for="item in items"
, no more v-for="items"
.v-for
on a component - it no longer automatically injects the data and meta properties like $index
and $key
into the component - you now need to explicitly pass them down using props. This makes the child component explicit about where its data comes from.The Web Components spec drafters are ditching the <content>
API in favor of <slot>
. Since Vue.js components are modeled after Web Components, and since the <slot>
API does make things more explicit than relying on CSS selectors, we are moving to the <slot>
API too.
The concept of multiple clauses (multiple directives separated by comma in the same attribute) is deprecated, and directive arguments are moved into the attribute name:
<!-- before: --> <div v-dirname="arg1: expression1, arg2: expression2"> <!-- after: --> <div v-dirname:arg1="expression1" v-dirname:arg2="expression2">
Using real directives as example:
<!-- before: --> <div v-on="click: doThis, keyup: doThat"> <!-- after: --> <div v-on:click="doThis" v-on:keyup="doThat">
There is no longer "literal directives" from the implementation perspective. All directives are reactive by default, which makes it easy to know whether an attribute value is an expression or a literal string. If you wish to pass the directive a literal string, use the following syntax:
<!-- before: no way to tell if this is a string or an expression! --> <div v-dirname="abc"> <!-- after: explicitly denoting a literal string --> <div v-dirname.literal="abc">
The ending .literal
is called a Binding Modifier, which forces the directive to be bound in literal mode. We will see this concept used below for prop binding types as well. In literal mode, the directive's update
function will be called once, with the literal string as the argument.
Mustache tags can only appear inside native attributes. To dynamically bind a custom attribute or a prop, use the v-bind
directive (which replaces v-attr
):
<!-- this is valid --> <a href="{{baseURL}}/abc"></a> <!-- these are no longer valid --> <component is="{{view}}"></component> <partial name="{{partialName}}"></partial> <!-- use v-bind for non-native attributes --> <component v-bind:is="view"></component> <partial v-bind:name="partialName"></partial>
Vue will raise a warning whenever mustaches are used in non-native attributes.
Previously props use mustaches to indicate reactivity. Now they must use v-bind
:
<!-- before --> <my-comp prop="a literal string" prop="{{expression}}"> <my-comp> <my-comp prop="a literal string" v-bind:prop="expression"> </my-comp>
Binding type indicators (@
and *
) are now replaced by more explicit binding modifiers:
<!-- before --> <my-comp prop="{{defaultOneWay}}" prop="{{@twoWay}}" prop="{{*oneTime}}"> </my-comp> <!-- after --> <my-comp v-bind:prop="defaultOneWay" v-bind:prop.sync="twoWay" v-bind:prop.once="oneTime"> </my-comp>
You may have noticed we will be using v-bind
and v-on
quite a lot. 1.0 will provide optional shorthand syntax for these two directives. v-bind:
can be shortened to a single colon :
, while v-on:
can be shortened to a single @
symbol:
<!-- attribute binding --> <img :src="imgSrc"> <!-- event handlers --> <input @click="handleClick" @keyup="handleKeyup"> <!-- props --> <my-comp :prop="expression" :prop.sync="twoWay" :prop.once="oneTime"> </my-comp> <!-- special attributes --> <component :is="view"></component> <partial :name="partialName"></partial>
If you are only using Vue as an enhancement on existing HTML pages, you may want to stick with the v-
prefixed versions. The shorthand is designed to make the template more succinct when you are building large SPAs where Vue manages everything. Don't worry about it not looking like valid HTML - all browsers can parse it just fine, and Vue removes all the special stuff in the rendered HTML anyway.
v-repeat
has been deprecated in favor of v-for
. Differences between v-for
and v-repeat
:
Required alias
Alias is required when using v-for
, and the item in items
syntax is preferred. It reads more naturally:
<li v-for="item in items"></li>
This also means the $value
meta property will no longer be used. $index
and $key
are still available. You can also still refer to the parent scope index in nested loops as $parent.$index
.
No more anonymous child VMs
Previously, v-repeat
creates an actual child VM instance with inherit: true
for every repeated block. This is no longer the case with v-for
: each repeated block in v-for
is now a real partially compiled fragment, with a lightweight intermediate "scope". This greatly reduces the overhead and as a result you should see significant performance improvement for both initial rendering (up to 100% for non-component loops) and re-rendering with track-by
(up to 50%, as tested in dbmonster).
This also means:
<template>
repeat no longer creates the overhead of a child instance.v-ref
would not work on v-for
if the repeated block is not a component, because there are no longer anonymous child instances created in that case.Component Scoping
Now this is the part that is the most different. Previously when you use a component with v-repeat
, you get somewhat weird scoping:
<!-- can't use $index here --> <comp v-repeat="item in list"></comp>
In the above example, item
and $index
are automatically available inside the component, but not in the parent template. If you do want to use $index
in the parent template, you have to create a <template>
to wrap the repeat. In addition, this requires the component implementation to be aware that it is v-repeat
specific, because the external data is not received via the standard props
interface.
With v-for
, you get the expected scoping:
<comp v-for="item in list" :id="$index" :data="item"> </comp>
And you need to explicitly pass external data into the component as props
. This makes your component implementation no longer v-repeat
specific and less magical.
v-for
also supports the v-for="(key, val) in obj"
or v-for="(index, val) in arr"
syntax. This allows nested loops to more easily reference the key or index.
v-for
no longer uses track-by="$index"
behavior for Arrays of primitive values by default. It now uses the value itself as the cache key. As a result, v-for
will raise warning when the Array contains duplicate values and prompt the user to use track-by="$index"
to handle duplicate values.
v-for
no longer converts the value to Array before piping it through filters. Custom filters used on v-for
will now get the raw value. However, the built-in filterBy
and orderBy
filters will convert the values into Arrays, so any filters after them will received the converted Array values.
v-class
and v-style
have been deprecated in favor of the new binding syntax (v-bind:class
and v-bind:style
). Bindings for class
and style
have some dedicated enhancements. You can pass in JavaScript Object or Array literals:
<!-- toggle classes --> <div v-bind:class="{ 'class-a': true, 'class-b': false }"></div> <!-- apply a list of classes --> <div v-bind:class="[ dynamicClass, 'literal-class' ]"></div> <!-- apply style object (camelCase accepted) --> <div v-bind:style="{ fontSize: '14px', color: 'red' }"></div> <!-- apply multiple style objects --> <div v-bind:style="[ styleObjectA, styleObjectB ]"></div>
You can use the .stop
and .prevent
modifiers for calling stopPropagation()
and preventDefault()
:
<!-- event won't propagate --> <a v-on:click.stop="doThis"></a> <!-- this will no longer reload the page! --> <form v-on:submit.prevent></form>
The key
filter for v-on
has been deprecated. v-on
can now leverage a Key Modifier that replaces the old key
filter (you can use all the old aliases usable in the key filter, or use a direct keyCode):
<!-- before --> <input v-on=" keyup: handleEnter | key 'enter', keyup: handleEsc | key 'esc'"> <!-- after --> <input @keyup.enter="handleEnter" @keyup.esc="handleEsc">
v-on
will now also listen to custom Vue events (emitted via vm.$emit
) when it is used on a child component. The idea is that props and events should constitute the public API of a component:
A typical component would look like this:
<item-list v-bind:items="items" v-bind:mode="active" v-on:ready="onItemsReady" v-on:update="onItemsUpdate"> </item-list>
With shorthand:
<item-list :items="items" :mode="active" @ready="onItemsReady" @update="onItemsUpdate"> </item-list>
v-el
and v-ref
were previously "literal" directives, but you just need to give them an argument. Also, to make things more explicit, vm.$
is now vm.$refs
, and vm.$$
is now vm.$els
.
<!-- child component ref, registers vm.$refs.child --> <comp v-ref:child></comp> <!-- elsewhere... --> {{$refs.child.msg}} <!-- element ref, registers vm.$els.node --> <div v-el:node></div>
Caveat: camelCase names are converted to all lowercase when the HTML is parsed:
<comp v-ref:someThing></comp>
Gets rendered as:
<comp v-ref:something></comp>
Thus, it is necessary to use the dash-case <-> camelCase mapping for refs too (similar to props):
<comp v-ref:some-thing></comp> {{ $refs.someThing.msg }}
multiple checkbox input can now be bound to the same v-model
value (must be an Array):
<input type="checkbox" value="Jack" v-model="checkedNames"> <input type="checkbox" value="John" v-model="checkedNames"> <input type="checkbox" value="Mike" v-model="checkedNames">
With checkedNames
' initial value being an Array, the checked boxes' values will be pushed into the Array, while unchecked ones will be removed from it. For example, if we check the first two boxes, checkedNames
will have the value ["Jack", "John"]
. Of course, you can also dynamically bind the value with v-bind
.
The options
param for <select v-model>
has been deprecated. You can now just use v-for
to render the options and it will work properly with the v-model
on the containing <select>
element.
v-else
directive. Docs<content>
outlet has been deprecated in favor of the new <slot>
API. Details$data
can no longer be used as a prop.data-
prefix are now longer supported.The orderBy
filter now expects its second argument to be a number instead of a boolean. The argument was originally called reverse
, and is now called order
. A value that is greater than or equal to 0
indicates ascending order, a value smaller than 0
indicates descending order. As a result, the old syntax for descending order still works:
<li v-for="user in users | orderBy 'name' -1"> {{ user.name }} <li>
The prefix
global config has been deprecated. All directives will now consistently use the v-
prefix.
The strict
global config has been deprecated. Asset resolution is now always in strict mode. Details
The interpolate
global config has been deprecated. Use v-pre
on elements that should be skipped by the template compiler.
The proto
global config has been deprecated. This has served no practical purpose and almost never used.
The inherit
option has been deprecated. Alway pass data to child components via props.
The $add
method has been deprecated for both Vue instances and observed objects. Use $set
instead. Details
Event propagation for events sent via $dispatch
and $broadcast
now stops when it triggers a handler for the first time, unless the handler explicitly returns true
. Details
$dispatch
now also triggers the event on the instance calling it.
Vue no longer extends Object.prototype
with $set
and $delete
methods. This has been causing issues with libraries that rely on these properties in certain condition checks (e.g. minimongo in Meteor). Instead of object.$set(key, value)
and object.$delete(key)
, use the new global methods Vue.set(object, key, value)
and Vue.delete(object, key)
.
Array.prototype.$remove
: now always treats the argument as the item to search for. (Previously it treats the argument as an index if the argument is a number).
Instance method vm.$addChild()
has been deprecated. Instead, a new option, parent
has been (re)introduced. The usage is pretty simple:
// before var child = parent.$addChild(options) // after var child = new Vue({ parent: parent })
Global asset registration methods, e.g. Vue.component
, now returns the registered asset. This means you can now create, globally register and get reference to a component constructor in one step:
var MyComponent = Vue.component('my-component', options) // equivalent to: var MyComponent = Vue.extend(options) Vue.component('my-component', MyComponent)
vm.$log()
messages now also include computed properties.
Prop expressions now support filters.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4