vue父子组件通信(二)祖先调用inject

inject 是 Vue 中的一个 依赖注入(Dependency Injection)机制,用于:

跨层级组件传值(祖先组件 → 后代组件)

它通常和 provide 配对使用。

作用是:

避免一层一层通过 props 往下传(prop drilling)。


1. 为什么需要 inject?

正常父子通信:

复制代码
复制代码
App
 └── Parent
      └── Child
           └── GrandChild

如果 App 的数据要给 GrandChild:

通常要:

复制代码
复制代码
App → Parent → Child → GrandChild

一级一级:

复制代码
复制代码
<Parent :theme="theme" />

再:

复制代码
复制代码
<Child :theme="theme" />

再:

复制代码
复制代码
<GrandChild :theme="theme" />

很麻烦。

于是 Vue 提供:

provide / inject

让后代组件直接拿。


2. 基本用法

祖先组件 provide

复制代码
复制代码
<script>
export default {
  provide() {
    return {
      theme: 'dark'
    }
  }
}
</script>

后代组件 inject

复制代码
复制代码
<script>
export default {
  inject: ['theme'],

  created() {
    console.log(this.theme)
  }
}
</script>

输出:

复制代码
复制代码
dark

即使中间隔了很多层组件,也能拿到。


3. 更完整例子

App.vue

复制代码
复制代码
<script>
export default {
  provide() {
    return {
      username: 'Tom'
    }
  }
}
</script>

<template>
  <Parent />
</template>

Parent.vue

复制代码
复制代码
<template>
  <Child />
</template>

不需要传 props。


Child.vue

复制代码
复制代码
<script>
export default {
  inject: ['username']
}
</script>

<template>
  <div>{{ username }}</div>
</template>

页面:

复制代码
复制代码
Tom

4. inject 和 props 的区别

对比 props inject
通信方式 父 → 子 祖先 → 任意后代
是否逐层传递 是 不需要
是否明确 明确 隐式
推荐场景 普通组件通信 全局/跨层级共享

5. 常见场景

① UI 组件库

比如:

复制代码
复制代码
<Form>
   <FormItem>
      <Input />
   </FormItem>
</Form>

Input 要知道:

  • label 宽度
  • 校验状态
  • form 配置

难道一级级 props?

不会。

通常:

复制代码
复制代码
provide('formContext')
inject('formContext')

Element Plus、Ant Design Vue 都大量使用。


② 全局配置

例如:

主题:

复制代码
复制代码
theme
locale
size
permission

③ 插件开发

Vue Router、Pinia、i18n 底层也用了类似机制。

比如:

复制代码
复制代码
app.provide(routerKey, router)

然后:

复制代码
复制代码
inject(routerKey)

拿 router 实例。


6. 响应式问题(重要)

很多人踩坑。

错误理解

以为:

复制代码
复制代码
provide() {
  return {
    count: 0
  }
}

改了会响应更新。

不一定。

因为普通值不是响应式共享。


正确方式(Vue3)

传 ref/reactive

复制代码
复制代码
import { ref } from 'vue'

const count = ref(0)

provide('count', count)

子组件:

复制代码
复制代码
const count = inject('count')

直接响应式更新。


7. Vue2 写法

复制代码
复制代码
provide() {
  return {
    user: this.user
  }
}

但:

复制代码
复制代码
this.user = 'new'

可能不更新。

Vue2 对 provide 响应式支持比较弱。

通常要:

复制代码
复制代码
provide() {
  return {
    state: this
  }
}

然后:

复制代码
复制代码
inject: ['state']

访问:

复制代码
复制代码
state.user

8. 一句话理解

props 是:

父组件显式传参

inject 是:

后代组件向祖先"拿依赖"

有点像 Java/Spring:

复制代码
复制代码
@Autowired
UserService userService;

祖先:

复制代码
复制代码
@Bean

后代:

复制代码
复制代码
@Inject

所以很多人把 Vue 的 provide/inject 理解成:

轻量级依赖注入(DI)机制。

相关推荐
啾咪orJIUMI43 分钟前
Vue 3 + 高德地图封装实战:点位、区域、Loca 流光与 Vue 信息窗体
前端·vue.js
掘金者阿豪1 小时前
AI数据库不只是向量检索:从数据语义到库内智能计算的技术演进
前端
梦里寻码1 小时前
我用 NestJS + Vue3 写了一套完整的研发管理系统(58 表 / 229 API / 130 项断言,全开源
前端·后端·算法
FRing031 小时前
vue2干货总结8(路由模块封装、router-link、声明式导航、路由重定向、编程式导航)
开发语言·前端·vue.js·vue2
SameX1 小时前
HarmonyOS ArkUI Dialog 复用 用 @CustomDialog + enum type 做多类型统一管理的做法
前端
AiMan1 小时前
豆包爱学还是不可以导出左侧所有对话,只能单容导出,方法不对吗
前端
无懈可击2 小时前
Vue 可视化AI表单设计器 FcDesigner v3.6 版本发布,支持导出 SQL功能!
vue.js·开源·ai编程
AiMan2 小时前
Grok生成的内容能否下载吗?
前端
徐小夕2 小时前
JitArchives,一款基于JitWord协同AI文档打造的企业级电子档案系统
前端·vue.js·github
陈随易2 小时前
Node.js 2026上半年都有哪些性能提升?
前端·后端·程序员