使用场景
解决跨层级传递属性的不方便而设立的,
看一个最简单的例子,从祖辈组件中拿到传入下来的颜色值
- 它可以是一个对象,比如
provide: {
color: "green"
}
- 访问this:一般还是用函数的方式,返回一个传入的对象
provide() {
return {
color: this.color,
};
}
inject: ["color"],
不是响应式
color
不是响应式的,就是说如果我在祖辈组件里选择另外一个颜色,在孙子组件里是拿不到更新后的值
第一种解决方案是把值转为函数,记得要用箭头函数,不然不能正确获取this
provide() {
return {
color: () => {
return this.color;
},
};
}
然后使用时就要变成了 color() 函数的调用
<template>
<div">传下来的颜色{
{color()}}</div>
</template>
这样子就带来一个很明显的缺点:如果在后代组件中多次使用,这个函数将会被调用多次
方案二: 更好一些的解决方案是把provide
所在的Vue实例给传递下去
provide() {
return {
color: this,
};
}
在孙组件里获得的其实是父组件的this,可以this.color获取父组件的颜色
<template>
<div>传下来的颜色{
{color.color}}</div>
</template>
可以看到很多UI组件库就是通过这个方式来传递属性的
provide链
若孙子组件中有同名的data,将会覆盖祖先传递的
export default {
data() {
return {
color: "blue",
};
},
inject: ["color"],
};
原理
一句话解释provide/inject
机制的原理——向上找寻。
首先在实例化Vue组件的时候,我们能看到初始化provide
和inject
的代码
其中initProvide
就是在当前实例中放入一个_provided
属性