watch 的 deep 和 immediate 参数怎么用?一招搞定初始化监听的痛点深度解析|Duuu笔记
watch 的 deep 和 immediate 是解决监听不到对象内部变化及首次加载不触发回调的刚需工具:immediate 使 watch 初始化即执行,deep 启用递归监听对象深层属性,二者组合可实现初始化+深度响应。
watch 的
deep
和
immediate
不是“锦上添花”的配置,而是解决两类典型问题的刚需工具:一个是监听不到对象内部变化,另一个是首次加载不触发回调。用对了,初始化逻辑就不用绕弯写两遍。
immediate:让 watch 第一次就干活
默认情况下,watch 只在数据“变化后”才执行,组件刚挂载时不会调用。如果你需要一上来就根据当前值做点事(比如拉取权限、校验初始状态、同步 UI),就必须加
immediate: true
。
handler 第一次执行时,
oldVal 是 undefined
,代码里要判断,避免报错
适合纯数据操作,比如发请求、更新本地状态;如果涉及 DOM(如聚焦输入框),仍建议在
mounted
中处理
Vue 2 和 Vue 3 写法略有不同:Vue 2 放在 watch 对象里,Vue 3 是 watch 函数的第三个参数对象中
deep:监听对象里每一层的变化
watch 默认只认“引用是否变”,不关心对象内部属性改没改。比如
form.user.name = '张三'
,顶层 form 引用没变,watch 就无感。这时开启
deep: true
,Vue 会递归遍历对象所有嵌套属性,给每个可响应的字段都加上监听。
ima.copilot
腾讯大混元模型推出的智能工作台产品,提供知识库管理、AI问答、智能写作等功能
下载
性能代价明显:对象越深、属性越多,开销越大;不要盲目给所有对象加 deep
仅对响应式对象有效;非响应式对象(比如通过 Object.assign 直接替换)或原始值(字符串、数字)不需要 deep
如果只关心某一个深层字段(比如
user.profile.avatar
),更高效的方式是直接监听该路径,而不是整个 user 对象
组合使用:初始化 + 深度响应
当你要监听一个对象,并且希望它一上来就执行、后续内部任意改动也都能捕获,就把两个选项一起用:
Vue 2 写法:
watch: { userInfo: { handler() { /* ... */ }, deep: true, immediate: true } }
Vue 3 Composition API:
watch(() => userInfo, () => { /* ... */ }, { deep: true, immediate: true })
注意:deep + immediate 组合下,handler 会立即执行一次(此时 oldVal 为 undefined),之后每次内部属性变化再触发
不复杂但容易忽略
