watcheffect 立即执行并自动追踪函数内读取的响应式数据,依赖变化时重运行;不追踪条件分支中未执行的代码或未访问的对象属性;返回 stop 函数用于手动停止,支持返回清理函数处理异步副作用。

watchEffect 的基础用法非常直接:传入一个副作用函数,它会立刻执行一次,并自动追踪该函数内部读取的所有响应式数据;只要其中任意一个值变化,函数就重新运行。
自动收集依赖的关键规则
它不靠你写什么“监听列表”,而是看函数体里实际访问了哪些响应式变量:
- 只追踪真正被读取的 ref 或 reactive 属性,比如写了 count.value 和 user.name,就只监听这两个
- 条件分支中未执行的代码不会纳入依赖,例如 if (show) { state.msg },只有 show 为 true 时,state.msg 才被追踪
- 同一 reactive 对象里没被访问的字段(如 user.email 没出现),哪怕值变了,也不会触发重运行
立即执行 + 响应式更新
和 watch 默认“惰性”不同,watchEffect 创建即运行——这对初始化逻辑很友好:
- 第一次调用会捕获当前所有依赖的快照,输出初始状态
- 后续只要任一依赖变更(比如用户点击按钮改了 count),整个函数重跑
- 不需要配置 immediate: true,这是它的默认行为
简单示例:控制台日志与多值联动
以下代码同时响应两个 ref 变化,无需声明依赖数组:
import { ref, watchEffect } from 'vue'
const count = ref(0)
const name = ref('Alice')
watchEffect(() => {
console.log(`count: ${count.value}, name: ${name.value}`)
})
// 点击按钮修改任一值,都会触发上面的日志更新
停止监听与基本清理
watchEffect 返回一个 stop 函数,组件卸载或需要手动停用时调用即可:
- 调用 stop() 后,函数不再响应变化,也不再收集依赖
- 若副作用含异步操作(如 setTimeout),可在函数内返回一个清理函数,它会在下一次执行前或 stop 时自动调用
- 例如:return () => clearTimeout(timer),确保旧定时器不干扰新逻辑











