watch 侦听源类型由传入参数形式决定:传 ref 追踪其 .value 变更(对象需 deep);传 reactive 天然深度响应;传 getter 函数则精准追踪内部读取的响应式依赖。

watch 侦听源类型不是靠“手动区分”,而是由你传入的参数形式决定 Vue 内部如何追踪变化。本质区别不在写法花样,而在「Vue 怎么理解你给它的那个东西」。
监听 ref:直接传 ref 变量,基础类型自动响应
ref 是一个带 .value 的响应式包装器。watch 接收 ref 实例时,会自动追踪其 .value 的变更:
- 基本类型(如 ref(0)、ref('hello')):值一改就触发,无需 deep
- 对象类型(如 ref({ a: 1, b: { c: 2 } })):默认只响应 .value 被整体替换(比如 obj.value = { a: 2 }),不响应 obj.value.b.c = 3 这类内部修改
- 要监听嵌套属性变化,必须加 { deep: true }——因为监听入口仍是 ref 实例本身,不是它内部的 reactive 对象
监听 reactive:直接传响应式对象,天然深度响应
reactive 返回的是 Proxy 代理对象,其响应式是深层的。watch 直接接收它时:
构建 Shopify 嵌入式应用(Embedded App)的开发技能:基于 @shopify/shopify-app-react-router + React Router v7 + Admin API 2026-04。覆盖 shopifyApp 配置、authenticate.admin 的 GraphQL/REST 调用、Webhook 校验、Session 存储、订阅计费、App Bridge 导航、部署,并新增:适用场景判断、安全最佳实践、错误处理与容错、最佳实践、常见问题 FAQ、高级场景。G
- 修改 user.name、user.profile.age、list.push(x) 都会触发回调
- { deep: true } 是冗余的,Vue 自动深度追踪
- 但注意:如果写成 watch(() => user, ...)(函数形式),那就变成监听函数返回值,此时需 deep: true 才能捕获对象内部变化
监听 getter 函数:用箭头函数包裹读取逻辑,最灵活也最常用
无论数据来自 ref 还是 reactive,只要在函数体内读取响应式属性,Vue 就会自动收集依赖:
- ref 场景:必须写 () => count.value 或 () => user.value.name
- reactive 场景:直接写 () => user.name 或 () => state.list.length
- 这种写法下,deep 通常不需要——Vue 会精确追踪函数中实际访问的响应式路径
- 适合监听特定字段、组合多个来源、或做计算逻辑(如 () => a.value + b.name)
小结关键逻辑
watch 不是“识别类型然后切换模式”,而是根据你传入的源,决定依赖追踪的起点和粒度:
- 传 ref → 追踪该 ref 实例的 .value 引用或内容(对象需 deep)
- 传 reactive → 追踪整个 Proxy 对象的任意属性变更(天然 deep)
- 传 getter 函数 → 运行一次函数,追踪其中所有被读取的响应式依赖(精准、推荐)

















