前言
阅读源码的之前,一直搞不懂这三个直接的关系,怎么触发,何时触发更新,何时收集依赖?带着这些问题阅读了2.6.12版本的源码,有点收获。
observer、watcher、dep
observer、watcher都叫做观察者,observer是观察属性变化的,watcher接受变化然后改变的,dep是依赖。
怎么触发依赖收集
observer监听了vm._data属性,然后劫持了getter跟setter属性。当执行mountCompnent函数时(也只有执行mountCompnent才会触发),就会触发了getter属性,这个时候watcher就会进行依赖收集,dep也会进行收集watcher(互相收集的过程)。
怎么触发更新
当执行this.name时,就相当于执行this._data.name,就会触发this._data.name的getter函数,这里进行更新操作,即dep.notify()。执行notify,就会执行dep收集的watcher的update函数,就会执行run函数。执行run以后,就会执行watcher的回调函数,也就是重新_render+_update。
问题
问题1. 查看源码的时候,发现了observer执行的时候,每一个key都有属于自己的dep,还需要递归value。这个如果使用proxy,就不需要递归value了,这里有着很大的性能优化。
问题2. 查看watcher的id时,没有发现id为1的watcher。通过阅读源码发现,options.computed跟options.watch会消耗掉watcher。所以整个vm的watcher一共只有三种,分别是watch的watcher,computed的watcher,以及mountComponent的watcher。