要使 inject 接收的值响应内部属性变化,需用 ref 或 reactive 包裹数据后 provide;inject 后须通过 .value 或属性访问触发响应追踪,不可直接解构;readonly 可实现只读但保持响应性。

要让 inject 接收到的值能正确响应内部属性变化,关键不是“让 inject 本身变响应”,而是确保 provide 端传入的是响应式引用(如 ref 或 reactive),且接收方以响应式方式访问其属性。
必须用 ref/reactive 包裹原始数据再 provide
直接提供普通对象或原始值(如字符串、数字)是**非响应式**的。即使后续修改该变量,inject 接收端也不会更新。
- ✅ 正确:用
ref或reactive创建响应式包装器,再传给provide - ❌ 错误:直接
provide('msg', this.message)(this.message是普通字符串)
inject 后需通过 .value 或属性访问触发响应追踪
inject 返回的是原样传递的响应式对象。Vue 的响应式系统只在你读取它的属性时建立依赖关系。
- 若提供的是
ref(0),注入后需用counter.value读取或修改,才能触发视图更新 - 若提供的是
reactive({ count: 0 }),注入后直接访问state.count即可响应 - 不能只解构响应式对象(如
const { count } = inject('state')),这会丢失响应性
避免常见陷阱:readonly 与响应性共存
有时你希望子组件只读、但依然能响应变化——这时用 readonly() 包装 ref 或 reactive 即可。
-
provide('config', readonly(configRef))→ 子组件可读config.value.xxx,但赋值会报错 - 响应性不受影响:只要源是响应式的,readonly 只限制写入,不切断依赖链
推荐结构:统一用 reactive + 解构式访问
对多字段状态更清晰、不易出错:
- 提供方:
const appState = reactive({ user: null, theme: 'light' }); provide('appState', appState) - 注入方:
const appState = inject('appState'); // 直接使用 appState.user、appState.theme - 模板中可直接
{{ appState.user?.name }},响应式生效










