inject 的数据需为 ref 或 reactive 才具响应性,watch 时应监听 ref.value 或显式 deep: true,避免解构破坏响应链,推荐 setup 中用 ref provide + watch 监听。

Inject 的数据默认不是响应式的,直接在 watch 中监听不会触发更新。要实现跨层级响应式联动,关键在于确保 provide 传递的是响应式引用(ref 或 reactive),并在 inject 时保持其响应性。
确保 provide 的数据是响应式的
provide 时必须传入 ref、computed 或 reactive 包裹的数据,不能传普通对象或原始值:
- ✅ 正确:provide('count', ref(0)) 或 provide('state', reactive({ x: 1 }))
- ❌ 错误:provide('count', 0) 或 provide('obj', { x: 1 }) —— 这样注入后失去响应性
inject 后直接 watch 响应式引用
inject 返回的如果是 ref,watch 时需加 .value;如果是 reactive 对象,watch 默认是深度监听(deep: true),但建议显式声明:
- watch(() => count.value, (newVal, oldVal) => {...}) // 监听 ref
- watch(state, (newVal, oldVal) => {...}, { deep: true }) // 监听 reactive 对象
- 也可用 watchEffect 自动追踪依赖,更简洁:watchEffect(() => console.log(count.value))
避免解构破坏响应性
不要对 inject 结果进行结构赋值,否则会丢失响应连接:
- ❌ 错误:const { count } = inject('countStore') —— 解构后 count 是普通数字,不再响应
- ✅ 正确:const countStore = inject('countStore'),然后 watch(() => countStore.count.value, ...)
- 或使用 toRefs(仅适用于 reactive 对象):const { count } = toRefs(inject('store'))
组合式 API 中的推荐写法
在 setup 或 script setup 中,统一用 ref 提供 + watch 监听最稳妥:
- 父组件 provide('theme', ref('dark'))
- 子组件 const theme = inject('theme'); watch(theme, (v) => console.log('主题变了:', v))
- 深层嵌套中,只要不中途赋值覆盖、不解构、不转成普通值,响应链就不断










