插件中的全局属性与 provide/inject
app.config.globalProperties.$myPlugin、使用 app.provide() 进行注入,以及 TypeScript 扩展
插件中的全局属性与 provide/inject 是 CoddyKit 上的免费 Vue Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Vue Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Vue Academy 课程共包含 4 节课。
公开服务的两种方式
插件可以通过两种方式共享功能:全局属性(经典的选项式 API 风格,通过 this.$x 访问)以及provide/注入(组合式 API 风格)。现代代码更倾向于使用 provide/注入;对于选项式 API 代码库,全局属性仍然很有用。
app.config.globalProperties
app.config.globalProperties.$http = client 会让每个选项式 API 组件都能使用 this.$http。按照惯例,属性应以 $ 开头,以避免与组件数据冲突。
import axios from 'axios'
export default {
install(app, options) {
const http = axios.create({ baseURL: options.baseURL })
app.config.globalProperties.$http = http
}
}在选项式 API 中使用 $http
在选项式 API 组件内部,可以通过 this 访问全局属性。
export default {
async created() {
const res = await this.$http.get('/users')
this.users = res.data
},
data() {
return { users: [] }
}
}为什么组合式 API 无法使用 this
在 <script setup> 中,没有绑定到组件实例的 this。因此 this.$http 无法工作。组合式 API 会改为读取注入的值,这是推荐的方式。
<script setup>
// this is undefined here, so this.$http is NOT available
// use inject() instead
</script>在插件中使用 provide
为了支持组合式 API,插件还应通过 app.provide 使用一个键提供同一个 service。两种方式都要提供:为选项式 API 提供全局属性,为组合式 API 使用 provide。
export const httpKey = Symbol('http')
export default {
install(app, options) {
const http = createHttp(options)
app.config.globalProperties.$http = http // Options API
app.provide(httpKey, http) // Composition API
}
}在组合式 API 中注入
组件通过 inject(httpKey) 读取 service。使用导出的 Symbol 键可以避免字符串拼写错误,并支持类型推断。
<script setup>
import { inject } from 'vue'
import { httpKey } from './plugins/http'
const http = inject(httpKey)
const res = await http.get('/profile')
</script>使用 InjectionKey 设置类型化注入键
要实现完整的类型安全,请使用 InjectionKey<T> 为键指定类型。这样,inject 就能自动推断出正确的值类型。
import type { InjectionKey } from 'vue'
import type { AxiosInstance } from 'axios'
export const httpKey: InjectionKey<AxiosInstance> =
Symbol('http')
// inject(httpKey) is now typed as AxiosInstance | undefined使用模块扩展为 $http 添加类型
要让 this.$http 具备类型安全,请在 .d.ts 文件中扩展 Vue 的 ComponentCustomProperties 接口。这样,TypeScript 就能在任何地方识别 this.$http 的类型。
// shims.d.ts
import type { AxiosInstance } from 'axios'
declare module 'vue' {
interface ComponentCustomProperties {
$http: AxiosInstance
}
}
export {}扩展应放在哪里
扩展必须是一个模块(注意末尾的 export {}),并且要包含在您的 tsconfig.json 中。请将它放在插件旁边,这样发布插件时类型也会随之提供。
// tsconfig.json (excerpt)
{
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.vue"]
}请谨慎使用全局属性
全局属性虽然方便,却会形成隐藏的依赖,使组件更难测试和推理。请优先使用 provide/注入(依赖明确且限定在组件树范围内)。只有真正适用于整个 app 且方便选项式 API 使用的工具,才应使用全局属性。
同时支持两种模式
完善的插件应同时支持选项式 API 和组合式 API:设置全局属性 AND 提供该值,并为全局属性和类型化注入键提供类型扩展。使用者可以根据组件风格选择合适的方式。
install(app, options) {
const service = build(options)
app.config.globalProperties.$service = service
app.provide(serviceKey, service)
}快速检查
请检验您对插件中的全局属性和 provide/注入的理解。
回顾
您学会了如何公开插件服务:
app.config.globalProperties.$http为选项式 API 的this.$http提供支持- 组合式 API 没有
this,而是使用inject - 同时提供全局属性和所提供的值,以实现完整覆盖
- 通过扩展
ComponentCustomProperties为this.$http添加类型 - 使用类型化的
InjectionKey处理注入路径
常见问题解答
「插件中的全局属性与 provide/inject」课时是免费的吗?
是的 — 「插件中的全局属性与 provide/inject」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Vue Academy 课程的其余内容,请升级到 CoddyKit PRO。 Vue Academy 课程共包含 4 节课。
「插件中的全局属性与 provide/inject」这节课中我会学到什么?
app.config.globalProperties.$myPlugin、使用 app.provide() 进行注入,以及 TypeScript 扩展 你通过在浏览器中直接运行的动手代码来练习 Vue Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Vue Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Vue Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「插件中的全局属性与 provide/inject」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Vue Academy 课中编写并运行代码吗?
能。每节 Vue Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 插件架构与 app.use()
- 插件中的全局属性与 provide/inject
- 通知与 Toast 插件示例
- 发布 Vue 插件并添加类型