参考资料:vue打包后的源码
学习方法:浏览器调试
使用的测试案例:
(一个模板对应一个renderWatcher,一个renderWatcher对应一个render function )
(data中的一个属性对应一个dep 例如 message对应dep(message)a对应dep(a)b对应dep(b))
(computed不对应dep)
<div>{{message}} {{a}} {{c}} {{a}} {{b}}</div>
data: {
message: 1,
a: 1,
b: 2
}
computed: {
c () {
return this.a + this.b + 22
}
}
listeners进行数据响应式
然后将computed中的属性进行响应式 并且为computed中的每一个属性生成一个computedWatcher对象【一个属性c对应一个computedWatcher对象】、并为该属性生成一个getter方法[c () {return this.a + this.b + 22}] 并将该属性进行数据响应式
程序往下执行,然后会一个new renderWatcher()
watcher的实例化过程会调用vm._update(vm._render()),
其中,vm._render会生成一个render函数,render函数执行的时候会获取指令模板中的值,进而触发各个属性(message a b c)的getter方法
getter方法中一方面获取到了值,另一方面完成了依赖搜集
message属性的getter触发 dep(message) [renderWatcher]
a属性的getter触发dep(a) [renderWatcher]
b属性的getter触发dep(b) [renderWatcher]
c属性的getter会执行this.a + this.b + 22 会调用a属性的getter和b属性的getter
进而使得
dep(a) [renderWatcher computedWatcher(c)]
dep(b) [renderWatcher computedWatcher(c)]
render函数获取完值之后,生成了vnode对象
调用vm._update(vnode) 进而调用vm.patch 完成视图的更新
==================================================================
当a的值发生改变时,
会触发dep(a) .notify
进而使得renderWatcher和computedWatcher进行处理(执行wathcer的update函数)
renderWatcher会进入到queueWatcher队列中,交由异步队列处理
computedWatcher会 if (watcher.lazy) watcher.dirty = true;将dirty设置为true
然后开始执行异步队列,进而执行renderWatcher.run(),进而调用vm._update(vm._render()) 后续过程同前文描述 【 这后面的过程还会去调用computedWatcher的getter函数获取值,这个时候重新进行依赖收集,数据更新】