依赖注入provide/inject
在 Vue 3 中,provide
和 inject
是用于依赖注入的一对 API,用来在组件树中传递数据。它们使得祖先组件可以向其所有后代组件提供数据,而不需要通过逐层传递 props。这在构建复杂的应用程序时非常有用,可以显著简化代码结构。
provide
和 inject
的作用
provide
: 用于在祖先组件中提供一个或多个依赖数据。inject
: 用于在后代组件中接收并使用祖先组件提供的依赖数据。
基本使用方法
1. provide
用法
在一个组件中使用 provide
来提供数据给其后代组件。通常在 setup
函数或 options API
中使用。
// 在祖先组件中
export default {
setup() {
const themeColor = ref('blue');
// 使用 provide 提供数据
provide('themeColor', themeColor);
return {};
}
}
在上面的例子中,provide('themeColor', themeColor)
将 themeColor
提供给了这个组件的所有后代组件。
2. inject
用法
在一个后代组件中使用 inject
来接收祖先组件提供的数据。也可以在 setup
函数或 options API
中使用。
// 在后代组件中
export default {
setup() {
// 使用 inject 接收数据
const themeColor = inject('themeColor');
return { themeColor };
}
}
在这个后代组件中,通过 inject('themeColor')
,我们可以接收从祖先组件中提供的 themeColor
。
实际示例
让我们结合一个实际的例子,展示 provide
和 inject
如何在 Vue 3 中工作。
<!-- App.vue -->
<template>
<div>
<h1>Main Component</h1>
<ChildComponent />
</div>
</template>
<script setup>
import { provide, ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
const color = ref('green');
// 在主组件中提供 color
provide('color', color);
</script>
<!-- ChildComponent.vue -->
<template>
<div>
<h2>Child Component</h2>
<GrandChildComponent />
</div>
</template>
<script setup>
import GrandChildComponent from './GrandChildComponent.vue';
</script>
<!-- GrandChildComponent.vue -->
<template>
<div :style="{ color: color }">
<h3>Grandchild Component</h3>
<p>The color from provide is: {{ color }}</p>
</div>
</template>
<script setup>
import { inject } from 'vue';
// 在孙组件中注入 color
const color = inject('color');
</script>
高级用法
1. 默认值
如果某个 inject
在祖先组件中没有找到对应的 provide
,你可以提供一个默认值:
const color = inject('color', 'red'); // 如果没有找到提供的 'color',默认值为 'red'
2. 响应式数据
因为 Vue 3 的响应式系统基于 ref
和 reactive
,当你提供响应式数据时,后代组件中注入的值也是响应式的。
3. Symbol 作为 key
为了避免不同 provide
和 inject
之间的冲突,你可以使用 Symbol
作为 key
。
const key = Symbol('myKey');
provide(key, ref('some data'));
const data = inject(key);
总结
provide
和 inject
是 Vue 3 提供的强大工具,简化了组件间的数据传递,尤其是在组件树较深时。它们让祖先组件能够将数据提供给任意深度的后代组件,而不需要通过 props 逐层传递,保持代码简洁和可维护性。