组件之间的新通信,适用于分支子组件之间,比如爷爷A下面的儿子BC,B下面的儿子E跟C下面的儿子F之间的通信(EVent Bus 早期都是使用如此,之前文章有demo)
这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效
写个简单的Demo(并不推荐使用,仅仅介绍使用方法,provide inject 会有一个类似冒泡的特性,数据源有可能在中间被”“打断”,甚至是有可能被组件库中的组件打断,或者打断组件库中的provide,不利于维护 )
<template>
<div>
<hr/>
<ChildrenA/>
<ChildrenB/>
</div>
</template>
<script>
import ChildrenA from './components/ChildrenA'
import ChildrenB from './components/ChildrenB'
export default {
components: {
ChildrenA,
ChildrenB
}
}
</script>
<style>
</style>
代码很简单,首先引入 A B 两个子组件,
A B 没其他代码,仅仅是进入子组件,使其C D成为孙子组件
provide(){
return{
foo:{
name:'Vue'
}
}
}
在App.vue的主组件申明,接下来我在C D 孙组件中接受
<template>
<div>
{{foo.name}}
</div>
</template>
<script>
export default {
inject:['foo']
}
</script>
<style>
</style>
使用inject接受,可以看到与props接收很类似,那么就可以直接在上方使用插值显示了
那么inject也可以类似prop一样做一些处理
inject:{
foo: {
from: 'foo',
default: () => [1, 2, 3]
}
}
如果是基础类型的话,default直接设置就行,并且此时没有provide的存在也可以使用(但是没有你用个啥)
这里有个from字段,这个是为了防止属性名重复一些操作
<template>
<div>
{{foos.name}}
</div>
</template>
<script>
export default {
inject:{
foos: {
from: 'foo',
default: () => [1, 2, 3]
}
}
}
</script>
<style>
</style>
这样哪怕我这边接受的是foos,但是数据来源还是foo
如果你的模板是函数式组件的话,就不能使用插值来获取了
D孙子组件
<template functional>
<div>
{{injections.foo.name}}
</div>
</template>
<script>
export default {
inject:{
foo:{
default:()=>{}
}
}
}
</script>
<style>
</style>
函数式组件这块后面可能会拎出来写一篇(主要是目前自己理解不是很好,怕误人子弟)
<template>
<div>
<hr>
<ChildrenA/>
<ChildrenB/>
<hr>
<button @click="change">Change</button>
</div>
</template>
<script>
import ChildrenA from './components/ChildrenA'
import ChildrenB from './components/ChildrenB'
export default {
components: {
ChildrenA,
ChildrenB
},
data(){
return{
name:'Vue'
}
},
provide(){
return{
foo:{
name:this.name
}
}
},
methods:{
change(){
this.name='newVue'
}
}
}
</script>
<style>
</style>
接下来写一个方法,让他改变,那么我在data中声明一个name,此时通过change改变这个name,但是很遗憾无法改变!(当然值是改变了,但是没法更新,因为此时子组件接受的数据并不是响应式)
直接给foo一个响应式返回(直接返回当前实例)
provide(){
return{
foo:this
}
},
此时就同时修改成功了
有一种情况就不演示了,就是如果我在父组件B的时候也调用一个provide,那么孙子组件是在冒泡找到这个数据的时候就停止了(所以这种情况先问过老大再使用吧!)
网友评论