Provide / Inject (依赖注入)

1. 面试题

Q: Provide / Inject 的原理是什么?它和 props 以及 Vuex 有什么区别?

2. 核心解答

依赖注入 是 Vue 实现跨层级 (祖先 -> 后代) 通信的核心机制。

(1) 使用方法

  • Provide: 在祖先组件中提供数据。
    provide('key', value)
  • Inject: 在任意后代组件中接收数据。
    const value = inject('key', defaultValue)

(2) 响应式问题

  • Provide 非响应式:如果 provide 的是一个普通对象 { a: 1 },它不是响应式的。
  • Provide 响应式:必须 provide 一个 refreactive 对象。
    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。