Provide / Inject (依赖注入)
1. 面试题
Q: Provide / Inject 的原理是什么?它和 props 以及 Vuex 有什么区别?
2. 核心解答
依赖注入 是 Vue 实现跨层级 (祖先 -> 后代) 通信的核心机制。
(1) 使用方法
- Provide: 在祖先组件中提供数据。
- Inject: 在任意后代组件中接收数据。
const value = inject('key', defaultValue)
(2) 响应式问题
- Provide 非响应式:如果 provide 的是一个普通对象
{ a: 1 },它不是响应式的。
- Provide 响应式:必须 provide 一个 ref 或 reactive 对象。
const count = ref(0)
provide('count', count)
- 单向数据流:建议同时 provide 一个
update 方法,让后代调用该方法来修改数据,而不是直接修改 ref。
(3) 实现原理
组件实例维护着一个 provides 对象。
默认情况下,子组件的 instance.provides 继承自父组件 (Object.create(parent.provides) )。
当 inject 时,顺着原型链向上查找。
(4) 场景对比
- Props: 父子通信。显式,清晰。
- Provide/Inject: 跨层级通信。
- 优点:避免透传 (Prop Drilling)。
- 缺点:数据来源隐晦。
- Pinia: 全局状态管理。
3. 面试加分项
Q: 什么时候用 Provide/Inject 替代 Pinia?
开发 UI 组件库 时(如 Form 组件传递验证规则给 FormItem),因为你不能强制用户安装 Pinia。