vue深入响应式原理学习

一、如何追踪变化

使用Object.defineProperty将传入的属性转换为setter/getter。每个组件实例有相应的 watcher实例对象,会在组件渲染时将属性记录为依赖,当相关依赖的setter被调用时,会通知watcher重新计算更新组件。
总结:每个实例有watcher监听变化,属性和实例之间通过Object.defineProperty方法转换。

vue深入响应式原理学习_第1张图片
数据与Virtual Dom

二、检测变化的注意事项

vue不能检测到对象属性的添加或删除。
所以vue在初始化实例对属性进行setter/getter转换过程时,属性必须在data对象上,才能做到响应式。

var vm = new Vue({
  data:{//初始化必须在data中
  a:1
  }
})
// `vm.a` 是响应的
vm.b = 2
// `vm.b` 是非响应的

添加新的属性:

Vue.set(vm.Object,key,value)//方法一
this.$set(this.Object,key,value)//方法二
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })
//方法三,创建新的对象,包含元对象的属性和新的属性。

三、声明响应式属性(提前声明所有的响应式属性)

由于Vue不允许动态添加响应式属性,所以必须在初始化实例前声明根基响应式属性,哪怕是空值。
data:{message:''}
如果在data中未声明message,vue将警告渲染函数在是试图访问的属性不存在(遇到好多次了)。
总结:vue不能动态更新根属性,属性需要提前声明,才能响应式,可以添加属性同步响应式。

四、异步更新队列(DOM实时更新)

watcher被触发时,数据不是立即变化重新渲染,而是推入队列中,当刷新队列时重新渲染。避免直接操作dom,又不得不操作时(比如echart图表)使用Vue.nextTick(callback)方法。回调函数在DOM更新完成后调用。在组件中自动绑定当前的Vue事例中。

Vue.component('example', {
  template: '{{ message }}',
  data: function () {
    return {
      message: '没有更新'
    }
  },
  methods: {
    updateMessage: function () {
      this.message = '更新完成'
      console.log(this.$el.textContent) // => '没有更新'
      this.$nextTick(function () {
        console.log(this.$el.textContent) // => '更新完成'
      })
    }
  }
})

你可能感兴趣的:(vue深入响应式原理学习)