provide 与 inject 是 vue 中祖先向后代注入响应式数据的轻量通信方案,通过 symbol key 提供 ref/reactive 数据,后代用 inject 获取并响应更新,适用于主题、国际化等深度嵌套场景。

Provide 与 Inject 是 Vue 中实现跨多层组件通信的轻量方案,适合祖先组件向后代组件“注入”响应式数据或方法,无需逐层 props 传递,也不依赖全局状态管理。
Provide:在祖先组件中定义可被注入的内容
在 setup() 中使用 provide() 函数,传入 key(字符串或 Symbol)和要共享的值。该值可以是响应式数据(ref、reactive)、函数,甚至整个组件实例。
- 推荐用 Symbol 作为 key,避免命名冲突:const themeKey = Symbol('theme')
- 若提供响应式数据,需用 ref 或 reactive 包裹,否则注入后失去响应性
- 可在 provide 中直接返回 computed 或调用后的函数,实现派生状态或封装逻辑
Inject:在任意后代组件中获取注入的内容
在 setup() 中使用 inject(),传入与 provide 相同的 key,即可获取值。支持设置默认值(非响应式),但注意默认值不能是 ref,否则会丢失响应性。
- 若注入的是 ref,直接解构赋值即可,模板中可直接用 {{ theme.value }}
- 若注入的是 reactive 对象,可安全地解构其属性(Vue 3.4+ 支持深层响应式解构)
- inject 返回值不是响应式代理时(如默认值),需手动用 ref 包裹再使用
典型使用场景与注意事项
适用于主题切换、国际化配置、表单上下文、UI 组件库内部通信等“一对多”、深度嵌套的场景。
- Provide 和 Inject 不是响应式“绑定”,而是“响应式引用传递”——修改注入的 ref.value 或 reactive 属性,所有 inject 处实时更新
- 不能在子组件 provide 后被父组件 inject,只能自上而下流动;也不支持反向通信
- 不建议用它替代 Vuex/Pinia,仅用于局部、明确的依赖注入关系
- 在 TypeScript 中,配合泛型可精准约束注入类型:inject
(themeKey)
简单示例:主题上下文注入
祖先组件提供主题色,子孙组件无论嵌套几层都能读取并响应变化:
- 祖先中:provide(themeKey, { color: ref('blue'), setColor: (c) => color.value = c })
- 后代中:const { color, setColor } = inject(themeKey),模板中用 {{ color }} 并可调用 setColor('red')
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











