Vue 3 中全局属性用于所有组件直接访问的常量或工具函数,需在 createApp 后、mount 前配置并声明 TypeScript 类型;provide/inject 用于跨层级响应式传递局部上下文数据,推荐用 Symbol 作 key,二者用途不同但可组合使用。

Vue 3 中全局属性和依赖注入是两种不同用途、不同作用域的机制,不能混用,但可以互补。关键不是“怎么一起配置”,而是“什么场景该用哪个、怎么配才不出错”。
全局属性:挂到 app.config.globalProperties 上,组件内用 this 访问
适合所有组件都需直接调用的常量、工具函数或调试开关(如 $apiUrl、$notify、$isDebug)。
- 必须在
createApp()之后、app.mount()之前设置 - 推荐统一加
$前缀(如$http),避免与组件自身属性冲突 - TypeScript 类型必须同步声明:在
vue-shim.d.ts或env.d.ts中补充接口 - 错误示例:定义了
globalProperties.isDebug = true,却在组件里写this.$isDebug→ 类型不匹配且值为undefined
provide / inject:祖先提供、后代注入,跨层级传递响应式数据
适合主题、用户状态、国际化配置等需要响应式更新、且只在部分组件树中使用的上下文数据。
- 不依赖
this,<script setup></script>中直接用provide()和inject() - 强烈建议用
Symbol作 key(如export const THEME_KEY = Symbol('theme')),防止命名污染 - 若提供的是响应式数据(
ref或reactive),注入后自动保持响应性;普通对象需手动包装 - 不适用于全局工具函数——它本质是“向下传递”,不是“随处可用”
别把两者当替代品,但可组合使用
例如:用全局属性挂载一个 $bus 事件总线实例,再用 provide/inject 把当前页面的业务状态(如表单校验结果)传给子组件。
立即学习“前端免费学习笔记(深入)”;
- 全局属性负责“通用能力”,provide/inject 负责“局部上下文”
- 不要在
provide里重复挂载router或pinia——它们已通过.use()自动注入,直接inject即可 - 大型项目中,可封装一个
setupProviders(app)函数,在main.ts统一注册所有 provide 逻辑,保持入口干净
常见踩坑点
- 在
setup()或<script setup></script>中试图用this.$xxx→ 错误!Composition API 下this不可用,应改用getCurrentInstance()?.appContext.config.globalProperties(不推荐),或直接走 provide/inject - 用字符串做 inject key,多个模块都叫
'config'→ 推荐全项目统一管理injectionKeys.ts - provide 的值是原始类型(如
provide('count', 1)),后代无法响应变化 → 改用provide('count', ref(1))


















