这几天看了tiny-emmity的源码,也了解了vue2中事件总线的具体流程和使用方法,在这里顺便就把vue组件通信的几种方式列举一下,方便日后自己回顾。
一、props / $emit
父组件通过props向子组件传递,子组件向父组件传值:子组件里用emit,父组件用@event监听
父->子 / 子 ->父
/**父组件*/
<template>
<div id="app">
<Bcom :message=msg @getBmsg="getbsmg"></Bcom>
</div>
</template>
<script>
import Bcom from 'views/test/Bcom'
export default {
components:{Bcom},
data(){
return{
msg:"B组件"
}
},
methods:{
getbmsg(bmsg){
console.log(bmsg)
}
}
}
</script>
/**子组件*/
<template>
<h1>{{msg}}</h1>
</template>
<script>
export default {
props:['msg'],
mounted() {
this.$emit('getBmsg','btoa')
}
}
</script>
二、 $attr / $listener
当两个组件是祖孙的关系时,如果要传递值,用prop可能就是逐个传递。
但vue2.4中新增的
a
t
t
r
/
attr/
attr/listener,可以直接解决向上或向下传递。
孙辈组件中能触发A中的函数是因为 B组件调用C的时候, 使用v-on绑定了 l i s t e n e r s 通 过 v − b i n d 绑 定 listeners 通过v-bind绑定 listeners通过v−bind绑定attrs, C组件可以直接获取到A组件传递下来的props,但除了B中用过的
A
<template>
<div id="app">
<Bcom
:bmsg="Bmsg"
:cmsg="Cmsg"
:BtoA="BtoA"
:CtoA="CtoA"
></Bcom>
</div>
</template>
<script>
import Bcom from 'views/test/Bcom'
export default {
components:{Bcom},
data(){
return{
Bmsg:"B组件",
Cmsg:"B组件",
}
},
methods:{
BtoA(){
console.log('b2a')
},
CtoA(){
console.log('c2a')
},
}
}
</script>
B
<template>
<h1>{{bmsg}}</h1>
<Ccom v-bind="$attrs" v-on="$listeners"></Ccom>
</template>
<script>
import Ccom from './Ccom'
export default {
props:['bmsg'],
components:{Ccom},
mounted() {
this.$emit('BtoA')
}
}
</script>
C
<template>
<h1>{{cmsg}}</h1>
</template>
<script>
export default {
props:['cmsg'],
mounted() {
this.$emit('CtoA')
}
}
</script>
三、provide/inject
祖先组件中通过provide提供变量, 然后在子孙组件中通过inject注入变量。
provide / inject API 主要解决了跨级组件间的通信问题,不过它的使用场景,主要是子组件获取上级组件的状态,跨级组件间建立了一种主动提供与依赖注入的关系。
这里的举例就以数据响应式形式,即祖先组件的变量值改变,子孙也会跟着一起改变
<template>
<div id="app">
</div>
</template>
<script>
export default {
data(){
return{
color:'red'
}
},
// provide (){
// return {
// theme:{
// color:this.color //此方式A组件color值变化,子孙组件不会变化
// }
// }
// },
// provide(){
// return {
// theme:this //方法一:提供祖先实例
// }
// },
// 方法二,使用vue2.6最新Api, Vue.observable
provide(){
this.theme = Vue.observable({
color:'blue'
});
return{
theme:this.theme
}
}
}
</script>
四、vue事件总线(V3移除)
vue3中移除了事件总线的功能,但提供了两个库 mitt(ts) 或 tiny-emitter(js)来代替。
我将会写一篇关于tiny-emitter的源码解析,总共也只有两百多行,不麻烦。
五、vuex
这部分内容比较重要,今后将单独写一篇文章