Vue计算属性依赖精准分发靠响应式系统读时收集、改时派发的闭环机制:读取时自动记录真实依赖,修改时仅通知相关计算属性,配合脏检查与缓存实现高效更新。

依赖收集发生在 getter 执行的一刻
当计算属性第一次被访问(比如模板里用到 {{ fullName }}),它的 getter 函数会同步运行。此时 Vue 正处于依赖收集状态,只要 getter 内部读取了响应式字段(如 this.firstName、author.books.length),就会触发该字段的 get 拦截器,进而把当前计算属性对应的 effect(Vue 3)或 Watcher(Vue 2)存入该字段的依赖列表中。
- 只收集真实访问的字段——没读到的,绝不会进依赖列表
- 支持深层访问:对象嵌套、数组索引、Map/Set 的 key 访问都会被正确 track
- 异步代码(
setTimeout、Promise.then)里读的数据不参与收集,因为那时已退出收集上下文
派发更新只触达真正受影响的计算属性
当某个响应式数据被修改(例如 this.firstName = 'Alice'),它的 set 拦截器立即执行 trigger(),遍历自身依赖列表,找到所有订阅了它的 effect 或 Watcher,并通知它们“你依赖的数据变了”。
- 计算属性对应的 effect 是 lazy 类型,收到通知后只设
dirty = true,不立刻重算 - 所有标记为 dirty 的计算属性,会在下一个微任务中统一调度、批量求值,避免重复或中间态更新
- 如果多个计算属性都依赖同一个字段(比如
a),它们会各自被独立标记并按需重算,互不影响
缓存机制保障“不变不重算”
计算属性的结果默认被缓存。只要依赖没变,后续访问直接返回 value,完全跳过 getter 执行。
递归分析 Vue 项目组件依赖,从入口文件生成组件层级图,支持 Vue 2/3,输出组件名、文件路径和属性。适用于分析组件结构、排查依赖或了解项目架构。
- 缓存是 per-computed 的——每个计算属性维护自己的
value和dirty标志 - 即使多个模板或其它 computed 引用了同一个计算属性,也共用同一份缓存和依赖关系
- 像
computed(() => Date.now())这种不依赖响应式数据的写法,永远返回初始值,因为没有依赖可追踪
与 methods 的本质区别就在这里
methods 是普通函数,每次调用都重新执行,不走响应式流程,也不记录依赖;而计算属性被 Vue 包装成一个带依赖追踪、脏检查、结果缓存三件套的响应式引用。是否参与精准分发,取决于它是否注册进了响应式系统的调度链路,而不是写法像不像函数。
立即学习“前端免费学习笔记(深入)”;

















