关于vue中数组与对象更新检测的问题

2018-05-30  本文已影响0人  sunshineLWZL

(1)数组更新检测

vue包含一些数组变异方法检测:push、pop、shift、unshift、reverse、sort、splice这些方法会导致数组的变异,也就是会替换调用这些方法的原有数组,vue对于这些方法做了劫持,在新的方法中手动触发了一次更新。

然而有些非变异数组方法不会修改原数组:filter、concat、slice这些操作并不会修改原数组,这些操作都会返回新的数组,因此可以对原有数组重新赋值,从而使得vue检测到数组的更新,如:

example1.items = example1.items.filter(function (item) {
 return item.message.match(/Foo/)
})

由于javascript的限制,Vue 不能检测以下变动的数组:

// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
// 也可以使用vm.$set
vm.$set(vm.items, indexOfItem, newValue)
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)

为了解决第二类问题,你可以使用 splice:

vm.items.splice(newLength)

(2)对象更新检测

还是由于 JavaScript 的限制,Vue 不能检测对象属性的添加或删除:

var vm = new Vue({
  data: {
    a: 1
  }
})
// `vm.a` 现在是响应式的
vm.b = 2

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

总结

无论对于数组还是对象,在javascript中都是存储在堆内存中,保存的其实是一个指向堆的指针,因此在对数组进行非变异方法,或则直接给对象添加或删除属性时,该指针并没有改变。从vue源码中可知,vue的双向绑定的核心其实就是使用的defineProperty,在给已创建的实例进行set操作时,会触发所有依赖该实例的其它实例的更新。而这些操作并没有修改原有的实例,没有触发set操作,从而也就不会触发其它包括视图的更新。而vue的set方法,进行赋值的同时,还会将这些数据变成响应式数据。

上一篇下一篇

猜你喜欢

热点阅读