vue源码解析之响应式原理

时间:2021-11-30 01:44:13

关于defineReactive等使用细节需要自行了解

一些关键知识点

  • $mount时 会 new Watcher 把组件的 updateComponent 方法传给watcher 作为getter

  • 在watcher的get中通过pushTarget 把当前watcher赋值给Dep.target

  • Dep的作用是调度中心/订阅器,在defineReactive 为每一个属性都实例话了一个Dep, 对用到该属性的Watcher进行管理(getter中收集,setter中通知)

  • Watcher是订阅者/观察者

  • 数据的Dep的subs数组存放这个数据所绑定的观察者对象,观察者对象的deps数组中存放着与这个观察者有关的数据Dep。所以数据的Dep与Watcher其实是多对多关系

  • $watch和computed观察者是在created生命钩子函数前就创建完毕并且绑定的,而render观察者是在mounted之前创建并绑定的,所以同一个组件中,render观察者的id会大于其他观察者(id是在后面执行队列里面升序排序的时候的依据)。 换句话说,在同一个组件的观察者中,当数据发生改变的时候,渲染函数观察者一定是最后执行的。 这个很好理解,其他观察者中难免会对数据进行修改,如果渲染函数观察者先执行了,然后其他观察者对数据进行改变的话,那么没办法将数据准确呈现在页面上,导致数据不一致性。

  • defineReactive --》 const dep = new Dep() --> getter中 --> dep.append() --> Dep.target.addDep(this) 这个this 就是当前dep实例 --> Dep.target是一个watcher watcher.addDep 会把当前watcher加入到 dep实例中。

流程图

vue源码解析之响应式原理