provide
和 inject
是 Vue.js 框架中的一对组合函数,用于实现跨组件层级的状态传递,通常用于开发者希望避免 props 的逐层传递(也称为 "prop drilling")时。这种模式在 Vue 2.2.0+ 中引入,并在 Vue 3.x 中得到了改进和支持。
provide
provide
函数允许你定义可以被子孙组件注入的数据或方法。在创建组件时,你可以在 provide
选项中指定想要提供给后代组件的数据。在 Vue 2.x 中,provide
是一个对象或者返回对象的函数;而在 Vue 3.x 中,provide
是一个函数,它接受两个参数:第一个是提供的属性的名称,第二个是属性的值。
Vue 2.x 示例:
export default {
provide() {
return {
theme: this.theme
};
},
data() {
return {
theme: 'dark'
};
}
};
Vue 3.x 示例:
import { provide } from 'vue';
export default {
setup() {
const theme = 'dark';
provide('theme', theme);
}
};
inject
inject
函数用于在任何子孙组件中接收来自祖先组件的 provide
的数据。inject
被用在那些需要获取数据的组件中,可以从最近的具有相应 provide
的祖先组件中获取数据。
Vue 2.x 示例:
export default {
inject: ['theme'],
created() {
console.log(this.theme); // 'dark'
}
};
Vue 3.x 示例:
import { inject } from 'vue';
export default {
setup() {
const theme = inject('theme');
console.log(theme); // 'dark'
return {
theme
};
}
};
区别
-
作用范围:
provide
用于定义要提供给子孙组件的数据。inject
用于接收来自祖先组件的数据。
-
使用场景:
- 使用
provide
和inject
可以避免多层嵌套组件之间通过 props 逐级传递数据的复杂性。 - 它们通常用于高阶插件/组件库的开发,或者在开发大型应用时,某些全局状态需要在多个深层嵌套的组件之间共享。
- 使用
-
反应性:
- 在 Vue 2.x 中,如果
provide
的数据是响应式的,那么注入的数据也将是响应式的;但如果直接提供了一个非响应式的对象,那么这个对象不会是响应式的。 - 在 Vue 3.x 中,
provide
和inject
都默认支持响应性。如果你提供一个响应式的引用(如reactive
或ref
创建的),注入的值也将保持响应性。
- 在 Vue 2.x 中,如果
-
版本差异:
- Vue 2.x 中的
provide/inject
绑定不是响应式的,除非提供的值是响应式对象。 - Vue 3.x 中改进了
provide/inject
,并且可以更好地与 Composition API 一起工作,使其成为构建可组合功能的强大工具。
- Vue 2.x 中的
provide
和 inject
提供了一种灵活的方式来跨组件传递数据,但它们也有可能使得组件间的依赖关系变得不那么明显,因此建议在确实需要的情况下谨慎使用,以保持应用的可维护性。