Built-In 指令

v-bind 真/假值 变更

在2.0中使用 v-bind 时,只有 null, undefined,和 false 被看作是假。这意味着,0 和空字符串将被作为真值渲染。比如 v-bind:draggable="''" 将被渲染为 draggable="true"

对于枚举属性,除了以上假值之外,字符串 "false" 也会被渲染为 attr="false"

注意,对于其它钩子函数 (如 v-ifv-show),他们依然遵循 js 对真假值判断的一般规则。

升级方式

运行端到端测试,如果你 app 的任何部分有可能被这个升级影响到,将会弹出failed tests

用 v-on 监听原生事件 变更

现在在组件上使用 v-on 只会监听自定义事件 (组件用 $emit 触发的事件)。如果要监听根元素的原生事件,可以使用 .native 修饰符,比如:

  1. <my-component v-on:click.native="doSomething"></my-component>

升级方式

运行端对端测试,如果你 app 的任何部分有可能被这个升级影响到,将会弹出failed tests

带有 debounce 的 v-model移除

Debouncing 曾经被用来控制 Ajax 请求及其它高耗任务的频率。Vue 中v-modeldebounce 属性参数使得在一些简单情况下非常容易实现这种控制。但实际上,这是控制了状态更新的频率,而不是控制高耗时任务本身。这是个微小的差别,但是会随着应用增长而显现出局限性。

例如在设计一个搜索提示时的局限性:

{{ searchIndicator }}

使用 debounce 参数,便无法观察 “Typing” 的状态。因为无法对输入状态进行实时检测。然而,通过将 debounce 与 Vue 解耦,可以仅仅只延迟我们想要控制的操作,从而避开这些局限性:

  1. <!--
  2. 通过使用 lodash 或者其它库的 debounce 函数,
  3. 我们相信 debounce 实现是一流的,
  4. 并且可以随处使用它,不仅仅是在模板中。
  5. -->
  6. <script src="https://cdn.jsdelivr.net/lodash/4.13.1/lodash.js"></script>
  7. <div id="debounce-search-demo">
  8. <input v-model="searchQuery" placeholder="Type something">
  9. <strong>{{ searchIndicator }}</strong>
  10. </div>
  1. new Vue({
  2. el: '#debounce-search-demo',
  3. data: {
  4. searchQuery: '',
  5. searchQueryIsDirty: false,
  6. isCalculating: false
  7. },
  8. computed: {
  9. searchIndicator: function () {
  10. if (this.isCalculating) {
  11. return '⟳ Fetching new results'
  12. } else if (this.searchQueryIsDirty) {
  13. return '... Typing'
  14. } else {
  15. return '✓ Done'
  16. }
  17. }
  18. },
  19. watch: {
  20. searchQuery: function () {
  21. this.searchQueryIsDirty = true
  22. this.expensiveOperation()
  23. }
  24. },
  25. methods: {
  26. // 这是 debounce 实现的地方。
  27. expensiveOperation: _.debounce(function () {
  28. this.isCalculating = true
  29. setTimeout(function () {
  30. this.isCalculating = false
  31. this.searchQueryIsDirty = false
  32. }.bind(this), 1000)
  33. }, 500)
  34. }
  35. })

这种方式的另外一个优点是:当包裹函数执行时间与延时时间相当时,将会等待较长时间。比如,当给出搜索建议时,要等待用户输入停止一段时间后才给出建议,这个体验非常差。其实,这时候更适合用 throttling 函数。因为现在你可以自由的使用类似 lodash 之类的库,所以很快就可以用 throttling 重构项目。

Upgrade Path

运行迁移工具找出使用 debounce 参数的 实例。

使用 lazy 或者 number 参数的 v-model 。替换

lazynumber 参数现在以修饰符的形式使用,这样看起来更加清晰,而不是这样:

  1. <input v-model="name" lazy>
  2. <input v-model="age" type="number" number>

现在写成这样:

  1. <input v-model.lazy="name">
  2. <input v-model.number="age" type="number">

升级方式

运行 迁移工具找到这些弃用参数。

使用内联 value的v-model 移除

v-model 不再以内联 value 方式初始化的初值了,显然他将以实例的 data 相应的属性作为真正的初值。

这意味着以下元素:

  1. <input v-model="text" value="foo">

在 data 选项中有下面写法的:

  1. data: {
  2. text: 'bar'
  3. }

将渲染 model 为 ‘bar’ 而不是 ‘foo’ 。同样,对 <textarea> 已有的值来说:

  1. <textarea v-model="text">
  2. hello world
  3. </textarea>

必须保证 text 初值为 “hello world”

升级方式

升级后运行端对端测试,注意关于v-model内联参数的 console warnings

v-model with v-for Iterated Primitive Values 移除

像这样的写法将失效:

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

因为 <input> 将被编译成类似下面的 js 代码:

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

这样,v-model 的双向绑定在这里就失效了。把 str 赋值给迭代器里的另一个值也没有用,因为它仅仅是函数内部的一个变量。

替代方案是,你可以使用对象数组,这样v-model 就可以同步更新对象里面的字段了,例如:

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

升级方式

运行测试,如果你的 app 有地方被这个更新影响到的话将会弹出failed tests提示。

带有 !important 的v-bind:style 移除

这样写将失效:

  1. <p v-bind:style="{ color: myColor + ' !important' }">hello</p>

如果确实需要覆盖其它的 !important,最好用字符串形式去写:

  1. <p v-bind:style="'color: ' + myColor + ' !important'">hello</p>

升级方式

运行 迁移帮助工具。找到含有 !important 的 style 绑定对象。

v-el 和v-ref 替换

简单起见,v-elv-ref 合并为一个 ref 属性了,可以在组件实例中通过 $refs 来调用。这意味着 v-el:my-element 将写成这样:ref="myElement"v-ref:my-component 变成了这样:ref="myComponent"。绑定在一般元素上时,ref 指 DOM 元素,绑定在组件上时,ref 为一组件实例。因为 v-ref 不再是一个指令了而是一个特殊的属性,它也可以被动态定义了。这样在和v-for 结合的时候是很有用的:

  1. <p v-for="item in items" v-bind:ref="'item' + item.id"></p>

以前 v-el/v-refv-for 一起使用将产生一个 DOM 数组或者组件数组,因为没法给每个元素一个特定名字。现在你还仍然可以这样做,给每个元素一个同样的ref

  1. <p v-for="item in items" ref="items"></p>

和 1.x 中不同,$refs 不是响应的,因为它们在渲染过程中注册/更新。只有监听变化并重复渲染才能使它们响应。

另一方面,设计$refs主要是提供给 js 程序访问的,并不建议在模板中过度依赖使用它。因为这意味着在实例之外去访问实例状态,违背了 Vue 数据驱动的思想。

升级方式

运行迁移工具找出实例中的 v-elv-ref

v-show后面使用v-else 移除

v-else 不能再跟在 v-show后面使用。请在v-if的否定分支中使用v-show来替代。例如:

  1. <p v-if="foo">Foo</p>
  2. <p v-else v-show="bar">Not foo, but bar</p>

现在应该写出这样:

  1. <p v-if="foo">Foo</p>
  2. <p v-if="!foo && bar">Not foo, but bar</p>

升级方式

运行迁移工具找出实例中存在的 v-else 以及 v-show