vue 事件总线EventBus的概念、使用以及注意点

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容器中有很多个一模一样的事件监听器这时就会出现,事件只触发一次,但监听事件中的回调函数执行了很多次

1.解决办法:在组件离开,也就是被销毁前,将该监听事件给移除,以免下次再重复创建监听
2.语法: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>

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,029评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,238评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,576评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,214评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,324评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,392评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,416评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,196评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,631评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,919评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,090评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,767评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,410评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,090评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,328评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,952评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,979评论 2 351