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 | 适合全局状态共享和复杂逻辑 |
通过合理使用 provide
和 inject
,可以高效实现跨级数据传递,但需结合项目复杂度选择合适方案。
更多细节可参考官方文档或上述引用的实战案例。