美文网首页
关于vue中数组与对象更新检测的问题

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

作者: sunshineLWZL | 来源:发表于2018-05-30 15:36 被阅读0次

    (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 不能检测以下变动的数组:

    • 当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue
    • 当你修改数组的长度时,例如:vm.items.length = newLength
      为了解决第一类问题,以下两种方式都可以实现和 vm.items[indexOfItem] = newValue 相同的效果,同时也将触发状态更新:
    // 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方法,进行赋值的同时,还会将这些数据变成响应式数据。

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/txatsftx.html