美文网首页
vue的响应式原理

vue的响应式原理

作者: 颖小李 | 来源:发表于2020-05-06 16:03 被阅读0次

    参考文章:深入响应式原理

    一、如何追踪变化?

    当你把一个普通的JS对象传入Vue实例作为data对象时,Vue将遍历此对象所有的property,并使用Object.defineProperty把这些property全部转为getter/setter。这些getter/setter对用户来说是不可见的,但是在内部它们让Vue能够追踪依赖,在property被访问和修改时通知变更。

    每个组件实例都对应一个watcher实例,它会在组件渲染的过程中把接触过的数据property记录为依赖。之后当依赖项的setter触发时,会通知watcher,从而使它关联的组件重新渲染。

    二、检测变化的注意事项

    对于对象,Vue无法检测property的添加或删除,但是我们可以通过以下办法来保证响应性:
    1.对于已经创建好的Vue实例,不允许动态添加根级别的响应式property。非根级别的,可以通过this.$set(object,propertyName,value)方法添加,会响应式变化。
    2.想给已有对象添加多个新property,并期望响应式变化。你应该这样写this.someObj = Object.assign({},this.someObj,{a:2,b:3}),而不是Object.assign(this.someObj,{a:2,b:3})

    对于数组,Vue无法检测以下变化:利用索引值直接设置数组项,vm.items[0]=2;修改数组的长度,vm.items.length = 2。那么应该怎么办?
    1.设置数组项,可以这样写来保证响应,Vue.set(vm.items, indexOfItem, newValue)vm.items.splice(indexOfItem, 1, newValue)
    2.修改数组长度,可以这样写,vm.items.splice(newLength)

    三、声明响应式property
    在初始化实例前声明所有根级响应式property,哪怕只是一个空值。

    四、异步更新队列
    Vue在更新DOM时是异步执行的。只要侦听到数据变化,Vue将开启一个队列,并缓冲在同一事件的循环中发生的所有数据变更。如果同一个watcher被多次触发,会在队列中去重,最终只执行一次。
    当你设置vm.someDate = 'new Val',该组件不会立即重新渲染,而是会在下一个事件循环中才会更新DOM里的值。如果希望在DOM更新之后做些什么,可以有两种写法Vue.nextTick(callback)或者await this.$nextTick()

    methods: {
        updateMessage: function () {
          this.message = '已更新'
          console.log(this.$el.textContent) // => '未更新'
          this.$nextTick(function () {
            console.log(this.$el.textContent) // => '已更新'
          })
        }
        或者
        updateMessage: async function () {
          this.message = '已更新'
          console.log(this.$el.textContent) // => '未更新'
          await this.$nextTick()
          console.log(this.$el.textContent) // => '已更新'
        }
      }
    

    相关文章

      网友评论

          本文标题:vue的响应式原理

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