Skip to content

vue 3 setup javascript 语法 provide 和 inject 跨级传值

在 Vue 3 的组合式 API 中,provide 和 inject 是实现跨级组件通信的核心工具。以下是其核心用法、注意事项及示例。

基本用法

父组件提供数据

从 vue 中导入 provide 和 ref/reactive,在 setup 中通过 provide(key, value) 传递数据。

vue
<script setup>
import { provide, ref } from "vue";

// 提供响应式数据
const name = ref("Vue3");
const age = ref(18);

provide("user", name);
provide("age", age);
</script>

子/孙组件注入数据

从 vue 中导入 inject,通过 inject(key, defaultValue) 获取数据。

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

const user = inject("user");
const age = inject("age");

// 也可以设置默认值
const age = inject("age", 18);
</script>

响应式处理

响应式数据:需用 ref 或 reactive 包装数据,否则子组件无法感知变化。

只读数据:使用 readonly 包装数据,防止子组件直接修改父组件状态。

父组件:

vue
<script setup>
import { provide, readonly } from "vue";

const count = ref(0);

// 子组件无法修改 count
provide("count", readonly(count));
</script>

注意事项

  • 使用范围:只能在 setup 或函数式组件中使用,不能在生命周期钩子或事件处理函数中调用。
  • 数据修改:建议通过父组件提供的方法修改数据,而非直接修改注入的值,以保持状态一致性。
vue
<script setup>
import { provide, readonly } from "vue";

// 父组件
provide("updateUser", (newName) => {
  user.value = newName;
});

// 子组件
const updateUser = inject("updateUser");
updateUser("New Name");
</script>

完整示例

父组件(App.vue)

vue
<script setup>
import { provide, ref } from "vue";
import Child from "./Child.vue";

const message = ref("Hello from Parent");

provide("message", message);
</script>

<template>
  <Child />
</template>

子组件(Child.vue)

vue
<script setup>
import { inject } from "vue";
import GrandChild from "./GrandChild.vue";
// 获取父组件数据
const message = inject("message");
</script>

<template>
  <GrandChild />
</template>

孙组件(GrandChild.vue)

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

// 直接获取祖父组件数据
const message = inject("message");
</script>

<template>
  <div>{{ message }}</div>
</template>

与其他通信方式对比

场景适用方案说明
直接父子通信Props + Emits简单直接,符合单向数据流原则
跨级组件通信Provide/Inject简洁灵活,但需注意状态管理
复杂状态管理Pinia/Vuex适合全局状态共享和复杂逻辑

通过合理使用 provideinject,可以高效实现跨级数据传递,但需结合项目复杂度选择合适方案。

更多细节可参考官方文档或上述引用的实战案例。