Vue中watch监听子组件状态最稳妥,支持Options API和Composition API两种写法,需注意响应式规则、deep/immediate配置及避免无限循环等边界情况。

直接用 watch 监听子组件内部状态变化,是 Vue 开发中最常用也最稳妥的方式。它不依赖父组件传值,也不需要事件总线或全局状态管理,适合处理本地逻辑响应。
监听 data 或 setup 中定义的响应式变量
在 Options API 中,直接在 watch 选项里写变量名即可:
- 基础类型(如 string、number):直接监听,无需额外配置
- 对象或数组需检测深层变动:加上
deep: true - 希望组件一创建就执行一次逻辑:加
immediate: true
示例(Options API):
data() { return { userInfo: { name: '', age: 0 } }; },watch: {
userInfo: {
handler(newVal, oldVal) { console.log('用户信息变了'); },
deep: true,
immediate: true
}
}
Vue 3 Composition API 中 watch 的正确写法
在 setup 里不能直接监听普通变量,必须确保监听目标是响应式引用:
- 监听 ref:直接传入 ref 变量(如
watch(countRef, ...)) - 监听 reactive 对象的某个字段:用
watch(() => state.name, ...)函数形式 - 监听整个 reactive 对象深层变化:仍需
deep: true,但注意性能
避免错误写法:不要对 reactive({}) 对象本身做 watch(obj, ...),这会丢失响应性。
跨组件通信的非常规技巧
不走 props / emit / provide / inject,也能实现轻量联动:
- 共享 ref:在父组件或 composable 中定义一个 ref,子组件 import 后直接 watch 它 —— 本质是共用同一响应式源
-
watch 路由参数:在子组件中监听
$route.params.id或$route.query,适用于页面级状态驱动子组件行为 -
监听 localStorage 变化:配合
window.addEventListener('storage', ...),适合多标签页协同场景(注意仅限同源) - 用 computed + watch 组合替代 deep watch:把复杂对象中真正关心的字段抽成计算属性,再 watch 这个计算属性,更精准、开销更低
注意事项和边界情况
有些变化 watch 捕捉不到,要提前规避:
- watch 不会响应通过
Object.assign或直接赋值新增的 reactive 对象属性(需用Vue.set或nextTick后再 watch) - 初始化时若值为 undefined,建议在 handler 中加守卫判断:
if (newVal === undefined) return - 避免在 watch 回调中直接修改被监听的变量,否则可能触发无限循环

















