Vue的provide/inject如何用
这篇文章主要讲解了“Vue的provide/inject如何用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Vue的provide/inject如何用”吧!
简单的可以把provide/inject对比为React的context,都是为了解决跨层级传递属性的不方便而设立的,跟早期的context一样,一开始provide/inject机制也没有载入官方文档,现在虽然已经写了,但仍是语焉不详,这就是我写本文的目的。
Hello World
看一个最简单的例子,从祖辈组件中拿到传入下来的颜色值
UI界面如上,很简单,祖辈组件还提供了一个单选来改变。
<template>
<div>
<label for="red">
红色
<input type="radio" id="red" value="red" v-model="color" />
</label>
<br />
<label for="greed">
绿色
<input type="radio" id="green" value="green" v-model="color" />
</label>
<slot />
</div>
</template>
先看provide,它可以是一个对象,比如
provide: {
color: "green"
}
在孙子组件中可以顺利的取到这个值,但要注意的是这样子的写法是不能返回Vue实例的响应式数据的,当尝试改为
provide: {
color: this.color, //访问不到Vue实例
}
发生错误,提示是Uncaught TypeError: Cannot read property 'color' of undefined 。
一般还是用函数的方式,返回一个传入的对象
provide() {
return {
color: this.color,
};
}
但是color不是响应式的,就是说如果我在祖辈组件里选择另外一个颜色,在孙子组件里是拿不到更新后的值的,关于非响应式这一点在下一节详细展开。
inject用来指定一个数组或者一个对象,数组的话就放provide里字段的名称,而对象的话可以指定
当前实例中的字段名
对应provide里的字段名
默认值或者返回默认值的函数
const Child = {
inject: {
foo: {
from: 'bar',
default: () => [1, 2, 3]
}
}
}
不是响应式
这个跟React的context是不同的,React没有响应式机制,一旦改变属性后默认会引发层层的渲染,开发者自己通过shouldComponentUpdate来优化。
官方文档上明确的说了
provide和inject绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的 property 还是可响应的。
第一种解决方案是把值转为函数,记得要用箭头函数,不然不能正确获取this
provide() {
return {
color: () => {
return this.color;
},
};
}
然后使用时就要变成了函数的调用
<template>
<div :style="{'color':color()}">传下来的颜色{{color()}}</div>
</template>
这样子就带来一个很明显的缺点就是由于不是响应式,这个函数将会被调用多次,比如上面模板里有两个color(),可以在函数里打个断点,会发现进来两次。
更好一些的解决方案是把provide所在的Vue实例给传递下去,再来改造一下
provide() {
return {
color: this,
};
}
在孙组件里获得的其实是实例了,所以要多取一层属性
<template>
<div :style="{'color':color.color}">传下来的颜色{{color.color}}</div>
</template>
可以看到很多UI组件库就是通过这个方式来传递属性的,因为有可能在不确定层级的子组件里要获得祖组件里的值。
感谢各位的阅读,以上就是“Vue的provide/inject如何用”的内容了,经过本文的学习后,相信大家对Vue的provide/inject如何用这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341