• Built-In 指令
    • v-bind 真/假值 变更
      • 升级方式
    • 用 v-on 监听原生事件 变更
      • 升级方式
    • 带有 debounce 的 v-model移除
      • Upgrade Path
    • 使用 lazy 或者 number 参数的 v-model 。替换
      • 升级方式
    • 使用内联 value的v-model 移除
      • 升级方式
    • v-model with v-for Iterated Primitive Values 移除
      • 升级方式
    • 带有 !important 的v-bind:style 移除
      • 升级方式
    • v-el 和v-ref 替换
      • 升级方式
    • v-show后面使用v-else 移除
      • 升级方式

    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>
    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 。替换

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

    <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-elv-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-refv-for 一起使用将产生一个 DOM 数组或者组件数组,因为没法给每个元素一个特定名字。现在你还仍然可以这样做,给每个元素一个同样的ref

    <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来替代。例如:

    <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