数据劫持: 在new Vue() 后,Vue会调用init()函数初始化,初始化的过程会创建Observer类用来观察在组件中定义的data,并使用object.defineProperty方法把data变成getter/setter的形式,这也就是数据劫持,当读取属性触发getter,修改属性触发setter。
其中定义了一个defineReactive()函数,这个函数里面用闭包来实现的,里面定义了一个中间变量,在getter里面直接返回这个中间变量,在setter里面把这个中间变量赋值为设置的值,就是通过这个函数来把一个普通对象变成getter/setter的形式。
如果对象有多个属性,就会调用Observer类里的walk方法去遍历该对象. 如果对象内有嵌套的属性就可以使用递归来完成嵌套属性的数据劫持.. 在getter方法里会收集依赖,在setter方法里会派发更新
依赖收集: 在vue中定义了一个watcher类就是依赖。它里面有get方法来获取数据和update方法来更新依赖。 当渲染页面解析模板时,会实例化watcher。遇到需要数据的地方就会实例化一个watcher,因此会有很多个watcher,那么就需要一个数组来管理这些watcher,vue中定义了一个Dep类来管理watcher。
dep类中定义了一个数组存放依赖也就是watcher,和depend方法来添加依赖,和notify方法通知依赖更新。 实例化watcher的时候会调用get方法来获取依赖的数据,而对数据进行了劫持那么就会触发getter函数,然后就在getter函数中会用dep实例的depend方法把当前的watcher添加到数组中,就完成了依赖收集。
派发更新 : 如果修改了属性的值就会触发对应的setter,在setter函数里就会遍历前面存放watcher依赖的dep数组,然后dep就会通知对应watcher,watcher就会调用自身的update方法去通知组件更新