Vue Computed 浅析
https://zhuanlan.zhihu.com/p/62732142 理解 Vue computed ,网上搜了一堆文章,都是一开始扔一堆概念,不好理解,这里整理一下。
这篇文章应该倒着看,首先需要理解 Vue 的依赖收集阶段干了啥,包括如何收集 watch
先假设以下代码
1 | <div>{{ b }}</div> |
主要问题在于 computed : 为什么改变 a 时,b 会自动计算? a 与 b 如何建立的联系?
依赖收集
页面更新,收集 computed。
Dep.target 设置为 页面 watcher。
- Dep.target: 类似一个状态,表示当前谁在收集,这里设置为 页面 watcher
- 页面 watcher: 表示页面收集状态为 收集全局变量状态
computed 被读取,createComputedGetter 包装的函数触发,第一次进行计算
调用 computed-watcher.evaluted,接着调用 computed-watcher.get ,Dep.target 被设置为 computed-watcher,旧值 页面 watcher 被缓存起来。
- computed 读取是一连串函数调用,读取时触发 data.get,进而拿到依赖的数据
- Dep.target 设置为 computed收集 状态
- 旧值 是页面收集全局变量时的值
- computed 会读取 data,此时 data 就收集到 computed-watcher
if (Dep.target === computed-watcher) computed依赖.push(data.value)
- computed-watcher 保存到 全局收集器列表: dep里
- 在 createComputedGetter 获取到对应的 watcher
- 对应的 watcher 就是文章开头时的 每个 computed 配发 watcher: 1、保存 computed 计算函数 2、保存计算结果 3、控制缓存计算结果是否有效
- computed 计算完成,Dep.target 恢复为 页面watcher
- 全局收集恢复到 收集computed 前的状态
- watcher.depend,让 全局收集 收集到 computed-watcher.dep 里的数据
- 于是 全局收集 里就有 computed 的 watch 数据了
整个依赖收集是同步执行的
设置 Dep.target 状态 ->
收集 computed ->
读取 data.value ->
触发 data.value.geter ->
加入到 computed.dep列表
缓存控制
依赖收集结束
- a 更新时通知 知道自己被 computed.b 收集了,于是将 computed.b 的
dirty
设置为 true 表示需要更新b的数据 - 之后通知 computed.b 让他更新数据