组件通信之事件总线 (eventBus)
eventBus
事件总线用的较多的是兄弟组件之间通信,当然 父子组件之间也适用,如何使用呢?
(1)需要创建一个事件中心
// bus.js
import Vue from 'vue'
export const EventBus = new Vue()
(2)兄弟间发送数据,假设现在有 A
和 B
两个兄弟组件
<template>
<div>
<A/>
<B/>
</div>
</template>
import A from './A.vue'
import B from './B.vue'
export default{
components: {
A,
B
}
}
在A
组件中发送数据
// A组件
<template>
<div>
<button @click="sendBrother">向兄弟B组件发送数据</button>
</div>
</template>
<script>
import {EventBus} from './bus.js'
export default {
data() {
name: 'A',
return {
n: '我是A组件'
}
},
methods: {
sendBrother(){
EventBus.$emit('hello', {
n: this.n
})
}
}
}
</script>
(3)接收数据,在B
组件接收数据
// B组件
<template>
<div>接收到兄弟A组件的数据为:{{aData}}</div>
</template>
<script>
import {EventBus} from './bus.js'
export default {
name: 'B',
data() {
return {
aData: ''
}
},
mounted() {
EventBus.$on('hello', data => {
console.log('我是A组件的数据', data)
this.aData = data
})
}
}
</script>
当然也提供了一些API
可以销毁EventBus
监听
EventBus.$off('事件名', callback)
,只移除这个回调的监听器。EventBus.$off('事件名')
,移除该事件所有的监听器。EventBus.$off()
, 移除所有的事件监听器,注意不需要添加任何参数。
注意:虽然这种方法看起来简单,但是这种方法也有很多不便之处,如果项目过大不建议使用这种方式。
EventBus的优缺点
- 如果你在某一个页面刷新了之后,与之相关的EventBus会被移除,这样就导致业务走不下去。
- 如果业务有反复操作的页面,EventBus在监听的时候就会触发很多次,也是一个非常大的隐患。这时候我们就需要好好处理EventBus在项目中的关系。通常会用到,在vue页面销毁时,同时移除EventBus事件监听。
- 由于是都使用一个Vue实例,所以容易出现重复触发的情景,两个页面都定义了同一个事件名,并且没有用$off销毁(常出现在路由切换时)。