Vue响应式系统中Track与Trigger是底层协作机制:读取时通过Proxy get拦截器在活跃effect中将当前effect加入属性对应的Set依赖集合,修改时通过set拦截器查找该Set并异步调度其中effect重新执行。

Vue响应式系统里的“Track”和“Trigger”不是两个独立的用户API,而是底层自动运转的一对协作机制:读取时记录谁在用(track),修改时通知谁重跑(trigger)。整个过程不依赖双向链表,核心是单向映射 target → key → Set
Track 是怎么发生的?
它发生在响应式数据被读取的瞬间,但仅当有活跃的副作用函数(比如组件渲染、computed、watch 或手动 effect)正在执行时才生效:
- 访问
state.count会触发 Proxy 的get拦截器 - 拦截器内部检查当前是否有正在运行的 effect(通过全局 activeEffect 栈判断)
- 如果有,就把这个 effect 添加进
count属性专属的依赖集合(本质是 Set)中 - 嵌套对象会逐层触发 get,实现深度依赖收集;数组则靠重写方法(如 push)主动触发 track
Trigger 又是怎么工作的?
它发生在响应式数据被修改时,目标明确、路径清晰:
Element Plus Vue3 桌面组件库。在开发 Vue 3.x 页面时调用,使用 Element Plus 组件(如 el-button、el-input、el-form、el-table 等)。
- 给
state.count = 5赋值,触发set拦截器 - 根据
target(state)和key('count')查到对应依赖集合 - 遍历该集合里所有 effect,并把它们推入异步调度队列(微任务)
- 同一 tick 内对同一个 effect 只调度一次,避免重复执行
手动控制 track/trigger 的真实用途
虽然日常开发几乎不用,但在高级场景中很关键。需要从 vue/reactivity 显式导入:
立即学习“前端免费学习笔记(深入)”;
-
track(target, TrackOpTypes.GET, key):在非响应式对象上“声明式”建立依赖,比如缓存对象 -
trigger(target, TriggerOpTypes.SET, key, newVal, oldVal):数据没变但视图要刷新时手动通知,例如外部拉取新数据后更新 UI -
pauseTracking()+resetTracking():批量读取响应式数据(如深克隆、diff)前暂停收集,防止无效依赖拖慢性能
常见误解澄清
这些说法容易误导初学者,需特别注意:
- Vue 响应式系统没有使用双向链表,也不维护“effect → deps”反向映射
-
track和trigger不是供你直接调用的工具函数,而是内部逻辑封装;暴露出来的同名 API 仅用于极少数定制场景 - 所谓“依赖收集”,本质是每个属性持有一个 Set,里面存着所有用过它的 effect,结构简单,查找高效
- DOM 事件监听、用户点击等行为本身不参与 track/trigger 流程;那是事件系统,和响应式系统无关

















