watcheffect是vue3自动依赖收集的响应式副作用监听器,初始化立即执行,依赖变化时自动重运行;无需显式指定监听源,但不可获取旧值、不支持深度监听,适用于简洁同步副作用场景。

watchEffect 是 Vue 3 中一个轻量、响应式、自动依赖收集的副作用监听工具,它会在初始化时立即执行一次,并在其中访问的响应式数据变化时自动重新运行。
watchEffect 的基本用法
它不需要显式指定监听源,而是通过执行函数时“读取”响应式变量,自动建立依赖关系:
- 传入一个函数,该函数内访问的
ref、reactive或computed会被自动追踪 - 函数首次定义后立刻执行(类似
mounted + watch合体) - 只要依赖项更新,函数就重新执行
示例:
import { ref, watchEffect } from 'vue'
const count = ref(0)
const message = ref('hello')
watchEffect(() => {
console.log('count:', count.value) // 追踪 count
console.log('message:', message.value) // 追踪 message
})
// 初始化输出:count: 0,message: 'hello'
count.value++ // 触发:count: 1,message: 'hello'
message.value = 'hi' // 触发:count: 1,message: 'hi'
控制副作用的执行时机与清理
watchEffect 支持接收第二个参数配置对象,常用选项包括:
-
flush: 'pre'(默认):在组件更新前执行(DOM 更新前) -
flush: 'post':在组件更新后执行(DOM 更新后),适合操作 DOM -
flush: 'sync':同步执行(不推荐,可能影响性能) -
onTrack和onTrigger:用于调试依赖收集和触发过程(开发阶段有用)
函数还可接收一个 cleanup 函数,用于清除上一次运行的副作用(比如取消未完成的请求、清除定时器):
let timer
watchEffect((onInvalidate) => {
onInvalidate(() => clearTimeout(timer)) // 上次执行的清理逻辑
timer = setTimeout(() => {
console.log('fetching...', searchQuery.value)
}, 200)
})
watchEffect 与 watch 的区别
关键差异在于依赖声明方式和使用场景:
-
watch:需明确列出要监听的源(数组或 getter),适合监听特定变化、执行异步或开销大的操作,支持 immediate 选项 -
watchEffect:自动追踪函数内读取的响应式值,更简洁直观,适合“响应即执行”的同步副作用(如日志、计算派生状态、简单 DOM 更新) -
watchEffect无法监听响应式对象的深层属性变化(除非用toRef或访问具体字段),也不支持监听多个不相关源的组合逻辑(此时更适合watch)
注意事项与常见陷阱
使用 watchEffect 要避免以下问题:
- 不要在回调中修改正在追踪的响应式数据,否则可能引发无限循环(例如在 effect 中改
count.value,而 effect 又依赖count) - 避免在条件分支里读取响应式变量——未执行的分支不会被追踪,导致依赖丢失
- 对
reactive对象,只追踪你实际访问的属性;若需监听整个对象变化,可用watch配合deep: true - 组件卸载时,watchEffect 自动停止,无需手动清理(但内部的定时器、请求等仍需自己处理)
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










