watchEffect 初始化立即执行并自动收集回调中实际读取的响应式依赖,后续仅当已收集的依赖变化时重新执行;依赖收集依赖 effect 上下文,且仅对 .value 或 reactive 属性访问生效。

watchEffect 会自动收集它回调函数里读取过的响应式数据,并在初始化时立刻执行一次;之后只要其中任一被读取的响应式值变化,就重新运行整个回调。
依赖怎么被“自动”收集?
Vue 在 watchEffect 执行回调的瞬间,会临时开启一个 effect 上下文。此时所有对 ref.value 或 reactive 对象属性的读取操作,都会被记录进依赖系统:
- 比如写了
count.value和user.profile.name,就只追踪这两个路径 - 如果用了条件判断:
if (show) { state.msg },那只有show为 true 时,state.msg才会被纳入依赖 - 没访问到的响应式字段,哪怕在同一对象里,也不会被监听
执行时机和触发逻辑
watchEffect 不是“监听某个变量”,而是“运行一段代码,并记住这段代码用到了哪些响应式数据”:
- 定义时立即执行一次(非惰性),用于建立初始依赖关系
- 后续每次依赖项变更,都会重新执行整个回调函数
- 每次执行都是全新的依赖收集——上一次没读的,这次读了,就会加入新依赖;上次读了、这次跳过,就会从依赖中移除
什么情况下依赖不会被收集?
不是所有读取都会进依赖系统,关键看有没有 effect 上下文包裹:
从零开始编排 SpringBoot+Vue 全栈项目工作流,适用于新建全栈项目或完整脚手架请求,触发后依次调用 product‑spec‑builder(需求调研)等模块。
立即学习“前端免费学习笔记(深入)”;
- 在普通函数里直接写
console.log(count.value),不触发收集 -
ref对象本身(如count)被读取,但没访问.value,不会收集(因为响应式逻辑在.value的 getter) - 在 setup 外、或未被 effect 包裹的异步回调中读取响应式数据,也不进依赖链
实际例子帮你理解
假设你写了这段代码:
const count = ref(0)const show = ref(false)
const user = reactive({ name: 'Alice' })
watchEffect(() => {
if (show.value) {
console.log('Hi', user.name, count.value)
}
})
初始执行时 show.value 是 false,所以只收集了 show.value;等你把 show.value = true,回调重跑,这时才开始追踪 user.name 和 count.value。它们变了,才会再次触发。

















