Built-In 指令
v-bind 真/假值 变更
在2.0中使用 v-bind
时,只有 null
, undefined
,和 false
被看作是假。这意味着,0
和空字符串将被作为真值渲染。比如 v-bind:draggable="''"
将被渲染为 draggable="true"
。
对于枚举属性,除了以上假值之外,字符串 "false"
也会被渲染为 attr="false"
。
注意,对于其它钩子函数 (如 v-if
和 v-show
),他们依然遵循 js 对真假值判断的一般规则。
升级方式
运行端到端测试,如果你 app 的任何部分有可能被这个升级影响到,将会弹出failed tests
用 v-on 监听原生事件 变更
现在在组件上使用 v-on
只会监听自定义事件 (组件用 $emit
触发的事件)。如果要监听根元素的原生事件,可以使用 .native
修饰符,比如:
<my-component v-on:click.native="doSomething"></my-component>
升级方式
运行端对端测试,如果你 app 的任何部分有可能被这个升级影响到,将会弹出failed tests
带有 debounce 的 v-model移除
Debouncing 曾经被用来控制 Ajax 请求及其它高耗任务的频率。Vue 中v-model
的 debounce
属性参数使得在一些简单情况下非常容易实现这种控制。但实际上,这是控制了状态更新的频率,而不是控制高耗时任务本身。这是个微小的差别,但是会随着应用增长而显现出局限性。
例如在设计一个搜索提示时的局限性:
{{ searchIndicator }}
使用 debounce
参数,便无法观察 “Typing” 的状态。因为无法对输入状态进行实时检测。然而,通过将 debounce
与 Vue 解耦,可以仅仅只延迟我们想要控制的操作,从而避开这些局限性:
<!--
通过使用 lodash 或者其它库的 debounce 函数,
我们相信 debounce 实现是一流的,
并且可以随处使用它,不仅仅是在模板中。
-->
<script src="https://cdn.jsdelivr.net/lodash/4.13.1/lodash.js"></script>
<div id="debounce-search-demo">
<input v-model="searchQuery" placeholder="Type something">
<strong>{{ searchIndicator }}</strong>
</div>
new Vue({
el: '#debounce-search-demo',
data: {
searchQuery: '',
searchQueryIsDirty: false,
isCalculating: false
},
computed: {
searchIndicator: function () {
if (this.isCalculating) {
return '⟳ Fetching new results'
} else if (this.searchQueryIsDirty) {
return '... Typing'
} else {
return '✓ Done'
}
}
},
watch: {
searchQuery: function () {
this.searchQueryIsDirty = true
this.expensiveOperation()
}
},
methods: {
// 这是 debounce 实现的地方。
expensiveOperation: _.debounce(function () {
this.isCalculating = true
setTimeout(function () {
this.isCalculating = false
this.searchQueryIsDirty = false
}.bind(this), 1000)
}, 500)
}
})
这种方式的另外一个优点是:当包裹函数执行时间与延时时间相当时,将会等待较长时间。比如,当给出搜索建议时,要等待用户输入停止一段时间后才给出建议,这个体验非常差。其实,这时候更适合用 throttling 函数。因为现在你可以自由的使用类似 lodash 之类的库,所以很快就可以用 throttling 重构项目。
Upgrade Path
运行迁移工具找出使用 debounce
参数的 实例。
使用 lazy 或者 number 参数的 v-model 。替换
lazy
和 number
参数现在以修饰符的形式使用,这样看起来更加清晰,而不是这样:
<input v-model="name" lazy>
<input v-model="age" type="number" number>
现在写成这样:
<input v-model.lazy="name">
<input v-model.number="age" type="number">
升级方式
运行 迁移工具找到这些弃用参数。
使用内联 value的v-model 移除
v-model
不再以内联 value
方式初始化的初值了,显然他将以实例的 data 相应的属性作为真正的初值。
这意味着以下元素:
<input v-model="text" value="foo">
在 data 选项中有下面写法的:
data: {
text: 'bar'
}
将渲染 model 为 ‘bar’ 而不是 ‘foo’ 。同样,对 <textarea>
已有的值来说:
<textarea v-model="text">
hello world
</textarea>
必须保证 text
初值为 “hello world”
升级方式
升级后运行端对端测试,注意关于v-model
内联参数的 console warnings
v-model with v-for Iterated Primitive Values 移除
像这样的写法将失效:
<input v-for="str in strings" v-model="str">
因为 <input>
将被编译成类似下面的 js 代码:
strings.map(function (str) {
return createElement('input', ...)
})
这样,v-model
的双向绑定在这里就失效了。把 str
赋值给迭代器里的另一个值也没有用,因为它仅仅是函数内部的一个变量。
替代方案是,你可以使用对象数组,这样v-model
就可以同步更新对象里面的字段了,例如:
<input v-for="obj in objects" v-model="obj.str">
升级方式
运行测试,如果你的 app 有地方被这个更新影响到的话将会弹出failed tests提示。
带有 !important 的v-bind:style 移除
这样写将失效:
<p v-bind:style="{ color: myColor + ' !important' }">hello</p>
如果确实需要覆盖其它的 !important
,最好用字符串形式去写:
<p v-bind:style="'color: ' + myColor + ' !important'">hello</p>
升级方式
运行 迁移帮助工具。找到含有 !important
的 style 绑定对象。
v-el 和v-ref 替换
简单起见,v-el
和 v-ref
合并为一个 ref
属性了,可以在组件实例中通过 $refs
来调用。这意味着 v-el:my-element
将写成这样:ref="myElement"
,v-ref:my-component
变成了这样:ref="myComponent"
。绑定在一般元素上时,ref
指 DOM 元素,绑定在组件上时,ref
为一组件实例。因为 v-ref
不再是一个指令了而是一个特殊的属性,它也可以被动态定义了。这样在和v-for
结合的时候是很有用的:
<p v-for="item in items" v-bind:ref="'item' + item.id"></p>
以前 v-el
/v-ref
和 v-for
一起使用将产生一个 DOM 数组或者组件数组,因为没法给每个元素一个特定名字。现在你还仍然可以这样做,给每个元素一个同样的ref
:
<p v-for="item in items" ref="items"></p>
和 1.x 中不同,$refs
不是响应的,因为它们在渲染过程中注册/更新。只有监听变化并重复渲染才能使它们响应。
另一方面,设计$refs
主要是提供给 js 程序访问的,并不建议在模板中过度依赖使用它。因为这意味着在实例之外去访问实例状态,违背了 Vue 数据驱动的思想。
升级方式
运行迁移工具找出实例中的 v-el
和 v-ref
。
v-show后面使用v-else 移除
v-else
不能再跟在 v-show
后面使用。请在v-if
的否定分支中使用v-show
来替代。例如:
<p v-if="foo">Foo</p>
<p v-else v-show="bar">Not foo, but bar</p>
现在应该写出这样:
<p v-if="foo">Foo</p>
<p v-if="!foo && bar">Not foo, but bar</p>
升级方式
运行迁移工具找出实例中存在的 v-else
以及 v-show
。