provide
和 inject
是 Vue.js 中用于依赖注入的一对 API,主要用于在组件树中跨层级传递数据。它们通常被用来避免多级组件层级之间的嵌套传递 props
。
基本用法
父组件(提供者)
父组件使用 provide
来提供想要共享的数据。
<template>
<div>
<ChildComponent />
</div>
</template>
<script>
export default {
name: 'ParentComponent',
provide() {
return {
message: 'Hello from Parent!'
};
}
};
</script>
子组件(使用者)
子组件使用 inject
来接收来自父组件或祖先组件提供的数据。
<template>
<div>
Injected Message: {{ message }}
</div>
</template>
<script>
export default {
name: 'ChildComponent',
inject: ['message']
};
</script>
说明
- provide: 在父组件中定义一个
provide
选项,可以是一个对象或返回对象的函数。这个对象中的所有属性都可以被其后代组件访问。 - inject: 在子组件中定义一个
inject
选项,这个选项是一个数组或对象,里面的属性名称对应于provide
提供的属性名称。
动态更新数据
默认情况下,provide
的数据不是响应式的。如果你需要动态更新提供的数据,可以将 provide
与 Vue.observable
或 ref
(在 Vue 3 中)结合使用。
在 Vue 2 中实现响应式 provide
<template>
<div>
<button @click="updateMessage">Update Message</button>
<ChildComponent />
</div>
</template>
<script>
import Vue from 'vue';
export default {
name: 'ParentComponent',
data() {
return {
state: Vue.observable({
message: 'Hello from Parent!'
})
};
},
provide() {
return {
state: this.state
};
},
methods: {
updateMessage() {
this.state.message = 'Updated Message!';
}
}
};
</script>
在 Vue 3 中实现响应式 provide
<template>
<div>
<button @click="updateMessage">Update Message</button>
<ChildComponent />
</div>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const state = ref({
message: 'Hello from Parent!'
});
const updateMessage = () => {
state.value.message = 'Updated Message!';
};
return {
state,
updateMessage
};
},
provide() {
return {
state: this.state
};
}
};
</script>
使用 provide 和 inject 的复杂用法
你还可以通过对象形式的 provide
和 inject
定义别名或默认值:
别名
// 父组件
provide() {
return {
originalMessage: 'Hello from Parent!'
};
}
// 子组件
inject: {
messageAlias: {
from: 'originalMessage'
}
}
默认值
inject: {
optionalValue: {
from: 'notProvidedByAncestor',
default: 'Default Value'
}
}
总结
provide
和inject
是 Vue.js 提供的用于跨组件通信的工具。- 适用于深层次组件树结构中避免 props 多层传递的问题。
- 可以与响应式状态结合使用,以实现对提供数据的动态更新。