加 immediate: true 可使 watch 回调在组件创建完成时立即执行一次,适用于初始化依赖 props、ref 初值或对象配置的场景,需作为 options 对象属性与 deep 等配合使用,首次 oldValue 为 undefined。

加 immediate: true 就行——它让 watch 回调在组件创建完成、监听器挂载好的那一刻,立刻用当前值执行一次,而不是等数据“变”了才动。
什么时候必须加 immediate
以下情况不加 immediate,逻辑就跑不通:
- 父组件传来的 prop 初始就有值(比如
props.productId),子组件需要一上来就根据它请求详情 - 表单字段从后端拉回默认值后,要立刻校验或触发联动(比如选中“北京”,马上加载“朝阳区”“海淀区”)
- setup 里用
ref初始化了一个变量,且赋了初值(如const searchKey = ref('vue')),你希望页面还没渲染完就先走一遍搜索逻辑
怎么写才对(Vue 3 script setup)
immediate 不是独立参数,必须作为 watch 的第三个参数(options 对象)里的一个属性,和 deep、flush 等并列。
✅ 正确写法:
const userId = ref('U1001')
watch(() => userId.value, (newId, oldId) => {
console.log('ID 变了或刚进来', newId)
}, { immediate: true })❌ 错误写法(像 Vue2 那样把 immediate 放错位置):
// 这样 immediate 不生效
watch(
() => userId.value,
{ immediate: true }, // 错:把配置当成了 handler
(newId) => { /* ... */ }
)配合 deep 一起用更常见
很多初始化数据是对象或数组,比如 props.config 或 ref({ theme: 'dark', lang: 'zh' })。这时往往要同时开 deep: true 和 immediate: true:
-
deep: true→ 监听到对象内部任意属性变化(如config.theme改了) -
immediate: true→ 第一次拿到完整 config 时就立刻应用主题、语言等设置
示例:
watch(() => props.config, (newConfig) => {
applyTheme(newConfig.theme)
setLanguage(newConfig.lang)
}, { immediate: true, deep: true })注意两个关键细节
首次执行时,oldValue 一定是 undefined —— 因为还没“上一次”的值。所以判断逻辑别踩坑:
- ✅ 推荐:
if (newVal && newVal.id) { ... } - ❌ 避免:
if (oldVal !== newVal) { ... }(首次永远为 true,可能引发误判)
另外,确保初始值是合法对象/数组,别是 null 或 undefined,否则开 deep 会报错“Cannot convert undefined or null to object”。

















