Provide / Inject Scope Demo
点击每个区域的 +1,它们互不影响,不会串起来。
相关文章: Vue provide/inject 与最近祖先取值
Detail Area
Quick Purchase Area
结论与解释
provide 可以理解为“向后代组件提供一份共享数据”;inject 可以理解为“后代组件按 key 取这份数据”。 它们用于跨层级传值,避免一层层 props 透传。
SharedPanel 内部调用的是 useScopedCounterStore()(本质是 inject)。 inject 的查找规则是:从当前组件开始,沿着组件树向上逐层查找谁 provide 了对应 key, 找到的第一个祖先就立即返回,这就是“从最近的祖先取值”。
这里的 key 在本 demo 里不是手写字符串,而是 createInjectionState(useScopedCounter) 在内部生成并管理的唯一 key(通常是 Symbol)。provideScopedCounter 和 useScopedCounterStore 共享同一个 key:前者负责 provide,后者负责 inject。
provideScopedCounter 的定义来源在 useScopedCounter.ts(由 createInjectionState 生成并导出),真正执行 provide 的位置在 ScopeProvider.vue(调用 provideScopedCounter(props.initial, props.mode))。
所以规则是:同一个 ScopeProvider 下的多个 SharedPanel 会共享同一份 store; 不同 ScopeProvider 下的 SharedPanel 互不影响;如果出现嵌套 ScopeProvider,内层会覆盖外层(因为更近)。
例子(伪结构):
ScopeProvider(Outer) ├─ SharedPanel-A // 读取 Outer └─ ScopeProvider(Inner) └─ SharedPanel-B // 读取 Inner(就近优先)