背景
由于Js的限制,vue不能监测到数组的变动。
Vue 双向绑定的原理是利用了 Object.defineProperty 重写了 get / set,以达到当属性的值发生变化时来更新试图的;但这有个缺陷,就是如果不是直接修改的属性,而是调用了变异方法,那么 Vue 并不知道其值已经发生改变,此时需要手动调用 Vue.set 以通知 Vue。为了缓解这个问题,Vue 对 Array 的7个方法进行了包装
var arr = [1,2,3]
arr[2] = 6
arr.length = 7
// [1, 2, 6, empty × 4]
复制代码
vue中两种操作方式将不会更新视图
- 直接通过索引修改数组,将不会更新视图
- 直接改变数组的length将不会更新视图
解决方案
Vue 是怎么知道你把一个对象的值改变以后、就能立刻让页面上显示的结果发生变化呢(所谓的双向绑定)。它是利用了 Object.defineProperty。
但 Object.defineProperty 有缺陷,只能识别出对属性直接赋值的,即 obj.property = newVal,这种情况下 Vue 才会知道有值变化了、该刷新视图了。
但对变异方法而言,Object.defineProperty 是无效的、无法得知值在变异方法中变化了。理论上,这种情况下,应该在代码中显示调用 Vue.set 来通知 Vue 有值变化了、该刷新视图了。
Vue 为了缓解这一问题,把 Array 的这几个变异方法做了包装,无需 Vue.set,Vue 也可以知道 Array 的值变化了、该刷新视图了。
vue 提供了数组的7个变异方法
总结
- Vue 包含一组观察数组的变异方法,所以它们也将会触发视图更新
- 也可以使用vue.$set来修改数组更新视图
- 不要直接修改数组的length,不要通过索引修改数组,将无法更新视图