immediate: true 使 watch 回调在创建时立即执行一次,解决初始值不触发监听的问题;需作为 options 对象属性与 deep 等配合使用,首次 oldValue 为 undefined。

watch 的 immediate: true 就是用来解决“组件一上来,数据已经存在,但监听器却没触发”这个常见痛点的。它让回调函数在侦听器创建完成的那一刻就立刻执行一次,而不是干等着后续变化。
什么时候必须加 immediate
以下场景加了 immediate 才能跑通逻辑:
- 父组件传来的 prop 初始就有值(比如商品 ID、用户配置对象),子组件需要一挂载就根据这个值发起请求或初始化状态
- 表单字段从后端拉取默认值后,要立即做校验或联动计算(比如选中省,马上加载市列表)
- 监听一个由 setup 中 ref 初始化的变量,且该变量在组件创建时已赋值,你希望首次渲染前就处理它
怎么写才正确(Vue3 script setup)
immediate 不是独立属性,必须作为 watch 第三个参数(options 对象)的一部分。错误写法会直接失效:
- ❌ 错误:把 immediate 写在 handler 外面一层(像 Vue2 选项式那样)
- ✅ 正确:和 deep、flush 等一起放在 options 对象里
示例:
const userId = ref('U1001')<br>watch(() => userId.value, (newId, oldId) => {<br> console.log('ID 变了或刚进来', newId)<br>}, { immediate: true })
配合 deep 使用更常见
很多初始化数据是对象或数组(比如 props.config、ref({a: 1, b: {c: 2}}))。这时 immediate 和 deep 往往一起上:
- deep: true 让监听穿透到嵌套属性
- immediate: true 确保第一次拿到完整对象时就触发处理
例如监听父组件传入的配置对象:
watch(() => props.config, (newConfig) => {<br> applyTheme(newConfig.theme)<br> setLanguage(newConfig.lang)<br>}, { immediate: true, deep: true })
注意边界情况
immediate 触发时,oldValue 是 undefined —— 因为还没“上一次”的值。所以判断逻辑里别直接用 oldVal === null 或做严格相等比较,优先看 newVal 是否有效:
- ✅ 推荐:
if (newVal && newVal.id) { ... } - ❌ 避免:
if (oldVal !== newVal) { ... }(首次 oldValue 是 undefined,永远为 true)

















