关于vue.js:vue-事件总线EventBus的概念使用以及注意点

50次阅读

共计 2285 个字符,预计需要花费 6 分钟才能阅读完成。

前言

vue 组件中的数据传递最最常见的就是父子组件之间的传递。父传子通过 props 向下传递数据给子组件;子传父通过 $emit 发送事件,并携带数据给父组件。而有时两个组件之间毫无关系,或者他们之间的结构复杂,如何传递数据呢?这时就要用到 vue 中的事件总线 EventBus 的概念

  • 公众号: 前端印象
  • 不定时有送书流动,记得关注~
  • 关注后回复对应文字支付:【面试题】、【前端必看电子书】、【数据结构与算法残缺代码】、【前端技术交换群】

注释

EventBus 的简介

EventBus 又称事件总线,相当于一个全局的仓库,任何组件都能够去这个仓库里获取事件,如图:

EventBus 的应用

废话不多说,间接开始应用 EventBus

一、初始化

要用 EventBus,首先要初始化一个 EventBus,这里称它为全局事件总线。

  • 第一种初始化办法
import Vue from 'vue'
// 因为是全局的一个 '仓库',所以初始化要在全局初始化
const EventBus = new Vue()     
  • 第二种初始化办法 (本文选用这种初始化办法)
// 在曾经创立好的 Vue 实例原型中创立一个 EventBus
Vue.prototype.$EventBus = new Vue()   

二、向 EventBus 发送事件

发送事件的语法:this.$EventBus.$emit(发送的事件名, 传递的参数)

曾经创立好 EventBus 后咱们就须要向它发送须要传递的事件,以便其余组件能够向 EventBus 获取。
例子:有两个组件 A 和 B 须要通信,他们不是父子组件关系,B 事件须要取得 A 事件里的一组数据 data

<!-- A.vue 这里是以模块化的形式解说的,即 A 组件和 B 组件别离各自
一个.vue 文件, 所以代码中会有导入的语法 -->

<template>
    <button @click="sendMsg"> 发送 MsgA</button>
</template>

<script> 
export default {data(){
      return{MsgA: 'A 组件中的 Msg'}
  },
  methods: {sendMsg() {
      /* 调用全局 Vue 实例中的 $EventBus 事件总线中的 $emit 属性,发送事
      件 "aMsg", 并携带 A 组件中的 Msg*/
      this.$EventBus.$emit("aMsg", this.MsgA);
    }
  }
}; 
</script>

三、接管事件

接管事件的语法:this.$EventBus.$on(监听的事件名, 回调函数)

A 组件曾经向全局事件总线 EventBus 发送了一个 aMsg 事件,这时 B 组件就能够去 aMsg 监听这个事件,并能够取得一些数据。

<!-- B.vue -->

<template>

  <!-- 展现 msgB -->
  <p>{{msgB}}</p>
  
</template>

<script> 
export default {data(){
    return {
      // 初始化一个 msgB
      msgB: ''
    }
  },
  mounted() {
    /* 调用全局 Vue 实例中的 $EventBus 事件总线中的 $on 属性, 监听 A 组件发送
    到事件总线中的 aMsg 事件 */
    this.$EventBus.$on("aMsg", (data) => {
      // 将 A 组件传递过去的参数 data 赋值给 msgB
      this.msgB = data;
    });
  }
};
</script>

B 组件展现后果:

 A 组件中的 Msg

这样,B 组件就轻松接管到了 A 组件传递过去的参数,并胜利展现了该参数,这样是不是就很简略的解决了各组件之间的通信呢?尽管 EventBus 是一个很轻便的办法,任何数据都能够往里传,而后被别的组件获取,然而如果用不好,容易呈现很重大的 BUG,所以接下来咱们就来解说一下移除监听事件。

四、移除监听事件

在上一个例子中,咱们 A 组件向事件总线发送了一个事件 aMsg 并传递了参数 MsgA,而后 B 组件对该事件进行了监听,并获取了传递过去的参数。然而,这时如果咱们来到 B 组件,而后再次进入 B 组件时,又会触发一次对事件 aMsg 的监听,这时工夫总线里就有两个监听了,如果重复进入 B 组件屡次,那么就会对 aMsg 进行屡次的监听。

总而言之,A 组件只向 EventBus 发送了一次事件,但 B 组件却进行了屡次监听,EventBus 容器中有很多个截然不同的事件监听器这时就会呈现,事件只触发一次,但监听事件中的回调函数执行了很屡次

  • 解决办法:在组件来到,也就是被销毁前,将该监听事件给移除,免得下次再反复创立监听
  • 语法:this.$EventBus.$off(要移除监听的事件名)
<!-- B.vue -->

<template>

  <!-- 展现 msgB -->
  <p>{{msgB}}</p>
  
</template>

<script> 
export default {data(){
    return {
      // 初始化一个 msgB
      msgB: ''
    }
  },
  mounted() {
    /* 调用全局 Vue 实例中的 $EventBus 事件总线中的 $on 属性, 监听 A 组件发送
    到事件总线中的 aMsg 事件 */
    this.$EventBus.$on("aMsg", (data) => {
      // 将 A 组件传递过去的参数 data 赋值给 msgB
      this.msgB = data;
    });
  },
  beforeDestroy(){
    // 移除监听事件 "aMsg"
      this.$EventBus.$off("aMsg")
  }
};
</script>

结束语

好了,对于 vue 中的事件总线的解说就到这里了,这也是我明天在做我的项目时用到的一个小知识点,接下来附上一张我因为没有及时移除事件监听,导致我每重进组件一次就报错 48 条错误信息的图,心愿大家在我的文章中能血啊都一些货色,并且不要再犯我的这种低级谬误。

正文完
 0