Vue响应式系统核心是建立“数据→副作用函数”的双向依赖映射,通过track/trigger机制、activeEffect标记和三层WeakMap结构实现按需收集与精准触发,ref与reactive统一于同一追踪流程。

Vue 响应式系统的核心逻辑不是单纯“监听数据变化”,而是建立并维护“谁在用什么数据”这一映射关系——依赖追踪器(Dep/Track-Trigger 机制)正是实现这一点的中枢。
依赖追踪器的本质:双向关联
它不单向地监视数据,而是动态构建“响应式数据 → 副作用函数”的绑定链路。每次读取响应式属性时触发 track,把当前正在执行的 effect(如组件渲染函数、computed getter)记入该属性的依赖集合;每次修改属性时触发 trigger,遍历该集合并重新执行所有 effect。
这个过程依赖两个关键支撑:
- 全局活跃 effect 标记(如 Vue 3 中的
activeEffect),确保 track 知道“此刻是谁在读” - 三层嵌套依赖结构:
WeakMap<target, Map<key, Set<effect>>>,既支持对象级代理,又避免内存泄漏
track 的触发时机与条件
track 并非在任意读取时都发生,只在effect 执行上下文内访问响应式数据时才收集依赖。例如:
立即学习“前端免费学习笔记(深入)”;
使用 `@ainative/vue-sdk` 为 Vue 3 应用添加 AI 聊天功能。适用于以下场景:(1) 安装 `@ainative/vue-sdk`,(2) 在 Vue 组件中使用 `useChat` 组合式函数,(3) 提供……
- 模板中 {{ count }} 渲染时,组件的 render effect 正在运行 → 触发 track
- 普通 JS 变量赋值
let x = obj.count(无 effect 上下文)→ 不收集 - ref.value 被读取时,内部 get 访问器自动调用 track
这意味着依赖关系是“按需建立”的,静态代码不会产生无效依赖。
trigger 的精准性与副作用执行
trigger 不是粗暴地刷新整个组件,而是精确通知所有与被修改 key 相关的 effect。比如:
-
obj.name = 'Alice'→ 只触发依赖name的 effect(如显示姓名的插值、相关 computed) -
obj.list.push(item)→ 对数组触发length和索引变更的 trigger,影响 v-for 渲染和 list.length 相关逻辑 - 修改 ref.value → 实际触发的是对
refObject.value这个属性的 trigger
所有被触发的 effect 默认异步批量执行(微任务队列),避免重复渲染。
ref 与 reactive 的依赖追踪差异
两者都参与同一套 track/trigger 流程,但入口不同:
-
reactive:通过 Proxy 的get拦截器统一触发 track,适用于对象及嵌套结构 -
ref:不走 Proxy,而是用get value()访问器,在读取.value时显式调用 track;当ref.value是对象时,内部自动转为 reactive,继续走 Proxy 路径
这种设计让原始类型也能纳入依赖追踪体系,同时保持行为一致性和透明拆包能力。

















