在 inject 时设置默认值可防止因祖先组件未 provide 而导致子组件访问 undefined 报错;需传入注入名和默认值,推荐用工厂函数避免副作用,并结合 TypeScript 泛型与 Symbol 键名统一保障类型安全与运行时健壮性。
在 inject 时设置默认值,是防止祖先组件没调用 provide 导致子组件拿到
、进而触发运行时错误(比如访问
或调用方法时报错)的关键做法。
inject 默认值的基本写法
inject 接收两个参数:注入名(字符串或 Symbol)和默认值。只要提供第二个参数,即使上层完全没 provide,也不会报错,而是直接返回该默认值:
→ 返回字符串
→ 返回对象
→ 返回 ref,保持响应性一致
用工厂函数避免副作用
如果默认值需要计算(比如创建新对象、发起请求、初始化类实例),应使用函数形式传入,确保只在真正需要时才执行:
❌ 错误:直接传对象
—— 每次 setup 都会新建实例
✅ 正确:
—— 只在未提供时才调用
常见场景:默认返回空 ref、空 reactive、空数组或 null 函数
配合类型安全(TypeScript)更稳妥
在 script setup 中结合泛型和默认值,能同时保障类型推导和运行时安全:
(推荐用工厂函数替代
)
类型标注 + 默认值,让 IDE 和编译器都能提前发现潜在问题
Symbol 键名下也要设默认值
用 Symbol 作为注入名虽可避免命名冲突,但不改变 inject 的行为逻辑——仍需显式设默认值:
即使键唯一,也不能假设它一定被 provide;默认值仍是防御性编码的必要一环
undefined.valueconst message = inject('message', '默认问候')const user = inject('user', { name: '游客', id: 0 })const theme = inject('theme', ref('light'))inject('api', createApiClient())inject('api', () => createApiClient())const count = inject>('count', ref(0))const store = inject('store', {} as Store) as Storeconst myKey = Symbol('myService')const service = inject(myKey, { init() {}, destroy() {} })