mcpField
P
provide-inject

provide-inject

github.com/patternsdev开发257187 次安装28 周前更新
代码仓库

关于 provide-inject

这项 Vue 技能介绍如何用 provide/inject 在组件树中共享数据,适合希望避免逐层传递属性的开发者。它以主题、语言区域和身份验证状态等横切数据为例。

主要功能

  1. 01从祖先组件提供数据
  2. 02在后代组件中注入值
  3. 03在应用级别共享数据
  4. 04避免逐层传递属性

适用场景

  1. 01在组件间共享主题设置
  2. 02让应用各处都能访问语言区域
  3. 03向后代组件提供身份验证状态

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/patternsdev/skills --skill provide-inject

安装后在 Claude Code 中输入/provide-inject确认已加载。

详细介绍

提供/注入

在管理父子组件之间的数据时,Vue 允许我们使用 props 将数据从父组件传递给子组件。Props 只能单向流动,从父组件流向子组件(并继续向下传递)。当父元素的状态发生变化时,Vue 会重新渲染依赖这些值的组件。

在大多数情况下,使用 props 效果很好。不过,在组件树中包含大量组件的大型应用中,props 可能会变得难以维护,因为组件树中的_每一个组件_都需要声明 props。

适用场景

  • 需要在深层嵌套的组件树中传递数据,且不想逐层传递 props 时使用
  • 适用于主题、区域设置或身份验证状态等应用范围的数据

不适用场景

  • 对于父子组件通信,props 更简单、更明确,也更容易追踪
  • 隐式依赖会让组件更难单独测试,或更难在提供者组件树之外复用时
  • 已经使用状态管理解决方案(Pinia),且该方案提供了相同的共享状态功能时

使用说明

  • 在父组件或祖先组件中使用 provide(),使所有后代组件都能访问数据
  • 在子组件中使用 inject() 访问提供的数据
  • 对整个应用都需要的数据(例如插件),使用应用级的 app.provide()
  • 对于仅限于特定组件集合的数据,优先使用 props;对于横切关注点,使用 provide/inject
  • 请注意,在包含许多提供者的大型应用中,使用 provide/inject 可能会让调试更加困难

详情

在考虑如何管理大量组件之间的数据时,通常最好采用可维护、易管理的方案来管理应用级状态(例如创建可复用的存储、使用 Pinia 等)。我们会在状态管理指南中详细介绍这一点。

不过,Vue 还提供了一种称为 provide/inject 模式的方案,帮助避免在 Vue 应用中复杂地逐层传递 props。

提供/注入

Vue 中的 provide() 函数允许我们在组件树中传递数据,而无需_逐层传递 props_(即在每一层手动向下传递 props)。另一方面,子组件会使用 inject() 选项访问父组件或任何祖先组件提供的数据或方法。

下面通过一个简单示例说明如何实现。假设有一个名为 App 的父组件,希望与名为 ChildComponent 的子组件共享一项数据。我们可以在父组件中使用 provide(),让所有子组件都能访问这项数据,而不是将其作为 prop 传递。

<template>
  <div id="app">
    <ChildComponent />
  </div>
</template>

<script setup>
  import { provide } from "vue";
  import ChildComponent from "./components/ChildComponent";

  provide("data", "Data from parent!");
</script>

然后,我们可以在 ChildComponent 中借助 inject() 函数访问这项数据。

<template>
  <div>
    <p>{{ data }}</p>
  </div>
</template>

<script setup>
  import { inject } from "vue";

  const data = inject("data");
</script>

在子组件(ChildComponent)中指定 inject("data") 后,我们就能直接访问父组件提供的 data 值。然后,我们将 data 绑定到模板,以显示其值。

使用 provide/inject 时,即使组件层级树中有很多子组件,也能看到相同的效果。借助 provide/inject,父组件 <App /> 中的数据可以在任意深层嵌套的子组件中渲染,而无需将数据逐层传递给树中的每个组件!

除了可以从父组件中使用 provide() 提供数据,我们也可以将 provide() 提升到应用级(即实例化 Vue 应用的位置)。

import { createApp } from "vue";
import App from "./App.vue";
import "./styles.css";

const app = createApp(App);

// app-level provide
app.provide("data", "Data from parent!");

app.mount("#app");

由于应用级提供的数据可供_所有_组件使用,因此在创建 插件时通常很有帮助。插件是为整个 Vue 应用添加功能的独立代码。

Props 与 provide/inject

什么时候该选择 props,什么时候该选择 provide/inject 模式?这两种方式各有优缺点。

使用 props:
  • 我们遵循一种清晰的模式,将数据逐级传递(优点)。
  • 但是,如果组件层级树包含大量组件,逐级传递 props 数据的过程可能会变得繁琐(缺点)。
使用 provide/inject
  • 子组件可以直接访问多个层级之上的父组件中的数据,无需在每个层级传递数据(优点)。
  • 但是,出现 Bug 时,使用 provide/inject 会让调试变得更困难。在包含许多不同提供者的大型应用程序中,这个问题会更加明显(缺点)。

provide/inject 模式最适合用于应用级客户端数据,例如主题信息、地区/语言偏好和用户身份验证详情。这类数据更适合使用 provide/inject 管理,因为应用中的任何组件都可能随时需要访问它们。

另一方面,如果数据只需在一组特定组件中隔离使用,那么 props 是理想的选择。

来源

参考资料

评论

支持 Markdown