组合式函数中应封装 inject 逻辑为 useInject,支持泛型、默认值、必填校验及环境差异化处理;配合 Symbol 键保障类型安全;按需扩展响应式访问器或插件级校验。
在组合式函数中封装依赖注入的获取与校验逻辑,核心是把 inject 调用、类型检查、默认值处理、缺失提示等统一抽象,避免每个组件重复写 const xxx = inject('key') 和防御性判断。
创建一个可复用的 useInject 组合式函数,接收 key、默认值、是否必填等参数:
示例代码:
import { inject, getCurrentInstance } from 'vue'export function useInject<T>(key: string | symbol,defaultValue?: T | (() => T),options: { required?: boolean; warnOnMissing?: boolean } = {}) {const instance = getCurrentInstance()const isProd = import.meta.env.PROD// 先尝试 injectlet value = inject<T>(key, undefined as any)// 若未注入且有默认值,按需解析if (value === undefined && defaultValue !== undefined) {value = typeof defaultValue === 'function' ? (defaultValue as Function)() : defaultValue}// 若仍为 undefined,按 required 策略处理if (value === undefined) {if (options.required) {const msg = `Missing required injection '${String(key)}'`if (isProd) {console.warn(msg)} else {throw new Error(msg)}}if (options.warnOnMissing && !isProd) {console.warn(`Injection '${String(key)}' not provided. Using fallback or undefined.`)}}return value}避免字符串 key 拼写错误或冲突,建议将所有注入名集中定义为 Symbol:
injections.ts 中统一导出 Symbol 键例如:
// injections.tsexport const ThemeSymbol = Symbol('theme')export const ApiClientSymbol = Symbol('api-client')// 在 provide 侧(如父组件或插件)import { ThemeSymbol } from './injections'provide(ThemeSymbol, reactive({ mode: 'light' }))// 在组合式函数中import { ThemeSymbol } from './injections'const theme = useInject(ThemeSymbol, { mode: 'dark' }, { required: true })某些场景下,不仅需要读取注入值,还需触发更新或监听变化(比如主题切换后刷新 UI),可进一步封装:
value 和 update 方法的对象(若提供者暴露了修改函数)computed(() => ...),自动追踪注入的 ref 或 reactive示例:
import { inject, computed, Ref } from 'vue'import { ThemeSymbol } from './injections'export function useTheme() {const theme = inject<Ref<{ mode: string }>>(ThemeSymbol)if (!theme) {console.warn('Theme injection not available')return {mode: computed(() => 'light'),setMode: () => {}}}return {mode: computed(() => theme.value.mode),setMode: (mode: string) => { theme.value.mode = mode }}}对于全局 app.provide() 注入的依赖(如 i18n、router、auth),可在插件安装时预设校验规则:
app.config.globalProperties.$xxx 或 app.provide 同时注册元信息app._context.provides 粗略判断,但不推荐直接访问私有属性)hasInjection(key) 工具供组合式函数调用实际项目中,多数情况只需聚焦前三个方案——类型化 Symbol + 带默认值/报错策略的 useInject + 场景化访问器,就能覆盖 90% 的通用需求。