ontrack 和 ontrigger 是 watcheffect 专用于开发模式调试的回调函数:ontrack 在依赖被读取收集时触发,ontrigger 在依赖变更导致副作用重执行时触发,二者均接收 debuggerevent 参数并仅在开发环境生效。

onTrack 和 onTrigger 是 watchEffect 专用于开发阶段调试的两个回调函数,仅在开发模式(process.env.NODE_ENV === 'development')下生效,生产环境会被忽略。它们不改变逻辑,但能帮你看清响应式依赖是如何被收集和触发的。
onTrack:看依赖是怎么被“盯上”的
每当某个响应式属性被读取、并被当前 watchEffect 收集为依赖时,onTrack 就会执行一次。它告诉你:“这个值正在被监听”。
参数 e 是一个 DebuggerEvent 对象,关键字段包括:
- target:被访问的对象(比如 reactive 的对象)
-
type:操作类型,常见值有
'get'(读取属性)、'has'(in 操作)、'iterate'(for...in / Object.keys 等遍历) -
key:触发依赖收集的具体键名(如
'count'),对 ref 是undefined(因为 ref 本质是通过 .value 触发 get)
示例:观察 reactive 对象中某属性何时被追踪
```tsconst state = reactive({ count: 0, name: 'vue' })
watchEffect(() => {
console.log(state.count) // 只读 count → onTrack 只会为 count 触发
}, {
onTrack(e) {
console.log('tracked:', e.key, 'on', e.target, 'type:', e.type)
}
})
```
onTrigger:看依赖变化后谁“动了手”
当某个已被追踪的依赖发生变更(set/delete),导致 watchEffect 重新执行时,onTrigger 被调用。它回答:“为什么这次又跑了?”
参数 e 同样是 DebuggerEvent,但关注的是变更行为:
- target:被修改的对象
-
type:变更类型,如
'set'、'delete'、'clear'(Map/Set) -
key:被修改的键(如
'count'),对 ref 是'value' - newValue / oldValue:仅在 set 类型中存在,便于对比
示例:点击按钮修改 count,观察触发源头
```tsconst state = reactive({ count: 0 })
watchEffect(() => {
console.log('effect run:', state.count)
}, {
onTrigger(e) {
if (e.type === 'set' && e.key === 'count') {
console.log('✅ count changed from', e.oldValue, 'to', e.newValue)
}
}
})
// 在模板中:
```
配合 flush 和 debugger 实现精准断点
onTrack/onTrigger 的典型用法是配合 debugger,在依赖收集或触发的关键节点暂停执行,方便查看调用栈和当前上下文。
- 把
debugger写进 onTrack/onTrigger 回调里,就能在依赖建立或变更瞬间中断 - 搭配
flush: 'post'可确保 DOM 已更新后再触发 onTrigger,适合调试与视图联动的逻辑 - 注意:不要在生产构建中保留这些回调,它们不会被 tree-shaken,且无实际作用
实用组合写法:
```tswatchEffect((onCleanup) => {
// 副作用逻辑
}, {
flush: 'post',
onTrack(e) { debugger },
onTrigger(e) { debugger }
})
```
常见调试场景与提示
遇到以下问题时,优先打开 onTrack/onTrigger:
- watchEffect 没有按预期重新执行 → 查 onTrack 是否成功收集到目标属性(比如误读了未定义字段)
- watchEffect 执行次数过多 → 查 onTrigger 是否因无关属性(如数组 length、Map size)被意外触发
- 监听 reactive 对象却没反应 → 确认是否读取的是对象本身(不会触发),而应读取具体属性(如
obj.name) - 异步请求被重复发起 → onTrigger 可帮你定位是哪个状态变更引发的连锁反应











