组合式 api 中处理可选祖先依赖注入需用 inject 默认值机制+类型守卫+响应式安全封装:必须显式提供 fallback 值,优先用 symbol 作注入名,配合可选链与工具函数校验,禁止直接修改响应式值。

在组合式 API 中处理可选的祖先依赖注入,核心是用 inject 的默认值机制 + 类型守卫 + 响应式安全封装,避免运行时报错或意外修改。
明确声明可选性,用默认值兜底
inject 第二个参数不是“备用值”而是“缺失时的 fallback”,必须主动提供,否则返回 undefined —— 这会引发后续 .value 或属性访问错误。
- 基础兜底:直接传基础值,如
inject('api', null)或inject('theme', 'light') - 函数式默认值:适合需懒初始化或含逻辑的场景,例如
inject('config', () => ({ timeout: 5000 })),函数只在未提供依赖时执行一次 - 避免误用 ref 默认值:不要写
inject('count', ref(0)),这会导致两个独立 ref;应传原始值或响应式对象本身
用类型断言 + 可选链保障运行时安全
尤其在 TypeScript 项目中,inject 返回类型默认为 T | undefined。不加判断就使用会触发类型错误或崩溃。
- 用可选链操作:如
api?.fetch?.()或store?.state?.user?.name - 用非空断言(谨慎):仅当你 100% 确保祖先一定提供时才用
inject('service')! - 封装校验逻辑:可抽成工具函数,例如
const requireInject = <t>(key: string, msg?: string) => { const v = inject<t>(key); if (v == null) throw new Error(msg || `Missing required injection: ${key}`); return v; }</t></t>
响应式值注入时,禁止直接赋值,暴露方法控制变更
即使依赖是可选的,一旦注入成功,它大概率是 ref 或 reactive 对象。后代组件不应直接改 count.value = 5,而应通过祖先暴露的 setter 或 action。
- 祖先提供时配套方法:如
provide('cart', { items, addItem, removeItem }) - 后代只调用方法:解构后使用
const { items, addItem } = inject('cart') || {},再判空调用 - 对可选响应式值做防御性读取:用
items?.value || []、isRef(items) ? items.value : items
用 Symbol 做注入名,避免字符串冲突和类型模糊
字符串 key 容易拼错、难追踪,且 TypeScript 无法推导类型。Symbol 是更健壮的选择。
- 定义唯一注入标识:
const CartSymbol = Symbol('cart')(建议统一放在 symbols.ts) - 祖先提供:
provide(CartSymbol, cartStore) - 后代注入并类型关联:
const cart = inject<cartstore>(CartSymbol)</cartstore>,TS 可自动推导非空类型(配合 strict 模式) - Symbol 天然不可枚举、不会被字符串污染,适合复杂应用或插件场景
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










