依赖收集发生在响应式数据被读取时,且必须处于活跃的副作用函数执行上下文中;Vue3 通过 Proxy 的 get 拦截器检查 activeEffect 并调用 track 将其加入 targetMap→depsMap→dep 三层结构。

依赖收集发生在响应式数据被读取时,且必须处于一个活跃的副作用函数(effect)执行上下文中——不是在定义数据时,也不是在组件挂载时,而是在首次渲染或计算逻辑运行过程中,真正访问 ref.value 或 reactive 对象属性的那一瞬间。
关键环节:get 拦截器触发 track
Vue3 用 Proxy 包裹响应式对象,所有属性读取都会经过 get 拦截器。此时系统会:
- 检查全局变量
activeEffect是否存在(即当前是否有 effect 正在执行) - 若存在,就调用
track(target, 'get', key),把activeEffect添加到该target的key对应的依赖集合中 - 这个过程不发生在
ref(0)或reactive({})调用时,而是在后续第一次count.value或state.count被读取时
典型触发场景:哪些代码会真正触发收集?
只有进入 Vue 管理的响应式副作用环境,读取行为才被记录:
递归分析 Vue 项目组件依赖,从入口文件生成组件层级图,支持 Vue 2/3,输出组件名、文件路径和属性。适用于分析组件结构、排查依赖或了解项目架构。
-
模板渲染:如
{{ count }}或v-if="show",编译后生成的 render 函数会访问响应式字段 -
computed:定义
computed(() => state.a + state.b)时,内部 effect 首次执行会分别收集a和b - watchEffect:传入的函数会被包装为 effect,立即执行并收集其中所有响应式依赖
-
watch:监听源(如
count)在初始化时也会读取一次,完成依赖登记
不会触发收集的常见情况
没有 effect 上下文包裹的读取,只是普通 JS 计算,不进依赖系统:
立即学习“前端免费学习笔记(深入)”;
- 在
console.log(count.value)中直接打印(非 setup 内部 effect 中) - 在普通函数里读取响应式数据,且该函数未被
effect、computed或watchEffect包裹 -
ref对象本身(如count)被读取,但没访问.value—— 因为 ref 的响应式逻辑在.value的 get/set 上
依赖存哪?结构怎么组织?
Vue3 用三层嵌套结构管理依赖关系,避免污染原始数据:
-
targetMap:WeakMap,键是原始响应式对象(如
state),值是它的depsMap -
depsMap:Map,键是属性名(如
'count'),值是该属性的依赖集合dep -
dep:Set,存放所有依赖该属性的
ReactiveEffect实例(比如组件渲染函数、watchEffect 回调)

















