watch监听响应式状态需把握三点:传对数据源(ref直接传、reactive属性用getter、多源放数组)、写好回调(接收新旧值)、按需加选项(immediate触发初始执行、deep开启深度监听)。

直接用 watch 函数监听响应式状态,核心就三点:传对数据源、写好回调、按需加选项。
监听单个 ref 变量
最常见也最直观的用法。ref 是响应式基础单位,watch 能自动追踪它的变化:
- 第一个参数传 ref 变量本身(不用加
.value) - 第二个参数是回调函数,接收新值、旧值两个参数
- 值变化时立即触发,初始绑定时不执行(除非加
immediate: true)
示例:
watch(count, (newVal, oldVal) => {
console.log(`从 ${oldVal} 变为 ${newVal}`)
})
监听 reactive 对象的某个属性
不能直接写 watch(obj.name, ...) —— 这样会丢失响应性。必须用 getter 函数包裹:
- 第一个参数写成箭头函数,返回要监听的属性值,比如
() => obj.name - 这样 Vue 才能正确建立依赖关系
- 如果监听的是对象或数组内部变化(比如 push 新元素),记得加
{ deep: true }
示例:
const obj = reactive({ list: [] })watch(() => obj.list, (newList, oldList) => {
// 数组内容变了也会触发
}, { deep: true })
监听多个响应式源
当逻辑需要同时关注几个变量时,把它们放进数组里传入:
- 第一个参数是 ref、getter 或它们的组合数组
- 回调函数的第一个参数是新值数组,第二个是旧值数组,顺序一一对应
- 所有源都变化后才触发一次回调,适合做联合判断
示例:
const a = ref(1)const b = ref('x')
watch([a, () => b.value], ([newA, newB], [oldA, oldB]) => {
console.log(`a: ${oldA}→${newA}, b: ${oldB}→${newB}`)
})
常用配置选项
第三个参数是可选配置对象,两个最实用的选项:
-
immediate: true —— 创建监听器时立刻执行一次回调,此时旧值为
undefined - deep: true —— 对对象或数组启用深度监听,内部任意嵌套属性变化都会触发
注意:deep: true 有性能开销,只在确实需要监听深层变更时开启。










