⾸先要了解Vue中的三个核⼼类:
1. Observer: 给对象的属性添加 getter 和 setter,⽤于依赖收集和派发更新
2. Dep: ⽤于收集当前响应式对象的依赖关系,每个响应式对象包括⼦对象都拥有⼀个 Dep 实例,,dep.subs是watcher实例的数组.,当数据有变更时,会通过 dep.notify()通知各个 watcher。
3. Watcher: 观察者对象, 实例分为三种
render watcher(渲染)
computed watcher(计算属性)
user watcher(侦听器)
上⾯提到了两个看起来⽐较⾼级的名词:
依赖收集
1. initState 时,对 computed 属性初始化时,触发 computed watcher 依赖收集
2. initState 时,对侦听属性初始化时,触发 user watcher 依赖收集
3. render()的过程,触发 render watcher 依赖收集
4. re-render 时,vm.render()再次执⾏,会移除所有 subs 中的 watcher 的订阅,重新赋值。
派发更新
1. 组件中对响应的数据进⾏了修改,触发 setter 的逻辑
2. 调⽤ dep.notify()
3. 遍历所有的 subs(Watcher 实例),调⽤每⼀个 watcher 的 update ⽅法。
总结⼀下原理:
当创建 Vue 实例时,vue 会遍历 data 选项的属性,利⽤ Object.defineProperty 为属性添加getter 和 setter 对数据的读取进⾏劫持(getter ⽤来依赖收集,setter ⽤来派发更新),并且在内部追踪依赖,在属性被访问和修改时通知变化。
每个组件实例会有相应的 watcher 实例,会在组件渲染的过程中记录依赖的所有数据属性进⾏依赖收集,之后依赖项被改动时,setter ⽅法会通知依赖与此 data 的 watcher 实例重新计算(派发更新),从⽽使它关联的组件重新渲染。