流程总结如下:
- 当组件初始化的时候,
computed和data会分别建立各自的响应系统,Observer遍历data中每个属性设置get/set数据拦截 - 初始化
computed会调用initComputed函数- 注册一个
watcher实例,并在内实例化一个Dep消息订阅器用作后续收集依赖(比如渲染函数的watcher或者其他观察该计算属性变化的watcher) - 调用计算属性时会触发其
Object.defineProperty的get访问器函数 - 调用
watcher.depend()方法向自身的消息订阅器dep的subs中添加其他属性的watcher - 调用
watcher的evaluate方法(进而调用watcher的get方法)让自身成为其他watcher的消息订阅器的订阅者,首先将watcher赋给Dep.target,然后执行getter求值函数,当访问求值函数里面的属性(比如来自data、props或其他computed)时,会同样触发它们的get访问器函数从而将该计算属性的watcher添加到求值函数中属性的watcher的消息订阅器dep中,当这些操作完成,最后关闭Dep.target赋为null并返回求值函数结果。
- 注册一个
- 当某个属性发生变化,触发
set拦截函数,然后调用自身消息订阅器dep的notify方法,遍历当前dep中保存着所有订阅者wathcer的subs数组,并逐个调用watcher的update方法,完成响应更新。
你可以在创宇前端微信公众号(KnownsecFED)或掘金社区读到这篇文章的全文。