Vuejs实践注意点

1.关于vue的响应式系统

当一个Vue实例被创建时,它向Vue的响应式系统中加入了其data对象中能找到的所有的属性。当这些属性的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。值得注意的是,只有当实例被创建时data中存在的属性才是响应式的。也就是说如果你添加一个新的属性,比如:

vm.b = 'hi'; // 添加vue实例的根元素

对于b的改动将不会触发任何视图的更新。如果你知道你会在晚些需要一个属性,但是一开始它为空或者不存在,那么你仅需要设置一些初始值。

注:使用Object.freeze(),这会阻止修改现有的属性,也意味着响应系统无法再追踪变化。

2.不要在选项属性或回调上使用箭头函数

不要在选项属性或回调上使用箭头函数,不要在选项属性或回调上使用箭头函数,比如created: () => console.log(this.a)vm.$watch('a', newValue => this.myMethod())。因为箭头函数是和父级上下文绑定在一起的,this不会是如你所预期的Vue实例,经常导致Uncaught TypeError: Cannot read property of undefinedUncaught TypeError: this.myMethod is not a function之类的错误。

3.计算属性的不同之处

计算属性是基于它们的依赖进行缓存的,只在相关依赖发生变化时它们才会重新求值。而普通的函数每次都会调用时都会重新执行。

4.监听器的使用

当需要监听某个对象的属性时,需要设置深度监听,不然无法监听到对象下某个属性的变化。

let vm = new Vue({
    data : {
        a: {
            b: 'b'
        }
    },
    watch:{
        a.b: {
            deep: true,
            handler: function(val, oldVal) {
                // ...
            }
    }
})

上面这种做法有个需要注意的地方,就是handler的回调函数中valoldVal的值相等,等于更新后的值。

需要监听多个属性的变化时,可以使用计算属性的特性来避免使用多个watcher

let vm = new Vue({
    data : {
        a: {
            b: 'b'
        },
        c: {
            b: 'b'
        }
    },
    watch:{
        bb: {
            handler: function(val, oldVal) {
                // ...
            }
    },
    computed: {
        bb: function() {
            return this.a.b + this.c.b;
        }
    }
})

监听构造出的计算属性即可达到同时监听这些属性的变化,当然,这只在他们的回调函数相同时有效。

5.v-if & v-else

v-ifv-else下的模板可能会被复用。Vue会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。如果不想复用元素,需要为元素添加一个唯一值的key属性。

6.v-if vs v-show

v-if是'真正'的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。v-if是惰性的,如果在初始渲染时条件为假,则什么都不做--直到条件第一次变为真时,才会渲染条件块。

v-show不管初始条件是什么,元素总是会被渲染,并且只是简单地基于CSS进行切换。

一般来说,v-if有更高的切换开销,v-show有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用v-show较好;如果在运行时条件很少改变,则使用v-if较好。

7.v-for遍历对象

v-for遍历对象时,是按照Object.keys()的结果遍历的,但是不能保证它的结果在不同的JavaScript引擎下是一致的。因为for..in的遍历就是无需的,各浏览器的顺序也不定。

Vue.jsv-for正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue将不会移动DOM元素来匹配数据项的顺序,而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。

为了给Vue一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一key属性。理想的key值是每项都有的且唯一的id

8.数组更新检测

以下变异方法更新数组会触发视图更新:

  • push()

  • pop()

  • shift()

  • unshift()

  • splice()

  • sort()

  • reverse()

非变异方法,需要用新数组替换旧数组触发视图更新:

  • filter()

  • concat()

  • slice()

Vue为了使得DOM元素得到最大范围的重用而实现了一些智能的、启发式的方法,所以用一个含有相同元素的数组去替换原来的数组是非常高效的操作。

Vue不能检测以下变动的数组:

  • 利用索引直接设置一个项时,例如:vm.items[indexOdItem] = newValue

  • 当你修改数组长度时,例如:vm.items.length = newLength

举个例子:

var vm = new Vue({
  data: {
    items: ['a', 'b', 'c']
  }
})
vm.items[1] = 'x' // 不是响应性的
vm.items.length = 2 // 不是响应性的

为了解决这个问题,可以使用vm.$set()实例方法或splice()更新数组。

9.对象更新检测注意事项

  • Vue不能检测对象属性的添加或删除

  • 对于已经创建的实例,Vue不能动态添加根级别的响应式属性。可以使用Vue.set(object, key, value)方法向嵌套对象添加响应式属性。

  • 需要为已有对象赋予多个新属性时,使用Object.assign()_.extend()。使用已有对象属性创建一个新对象然后赋值。

Last updated