组件通信之事件总线

44 阅读1分钟

组件通信之事件总线 (eventBus)

eventBus事件总线用的较多的是兄弟组件之间通信,当然 父子组件之间也适用,如何使用呢?

(1)需要创建一个事件中心

// bus.js
import Vue from 'vue'
export const EventBus = new Vue()

(2)兄弟间发送数据,假设现在有 AB两个兄弟组件

<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销毁(常出现在路由切换时)。