08.Vue事件总线(EventBus)

vue组件非常常见的有父子组件通信,兄弟组件通信。而父子组件通信就很简单,父组件会通过 props 向下传数据给子组件,当子组件有事情要告诉父组件时会通过 $emit 事件告诉父组件。今天就来说说如果两个页面没有任何引入和被引入关系,该如何通信了?

如果咱们的应用程序不需要类似Vuex这样的库来处理组件之间的数据通信,就可以考虑Vue中的 事件总线 ,即 EventBus来通信。

一.EventBus事件总线简介

EventBus又称事件总线,相当于一个全局的仓库,任何组件都可以去这个仓库里获取事件

img

二.事件总线(EventBus)的使用

2.1 事件总线的初始化

img

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

2.1.1 第一种初始化方法

import Vue from 'vue'
//因为是全局的一个'仓库',所以初始化要在全局初始化
const EventBus = new Vue()     

2.1.2 第二种初始化方法(本文选用这种初始化方法)

//在已经创建好的Vue实例原型中创建一个EventBus
Vue.prototype.$EventBus = new Vue()   
import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

//给Vue绑定属性
Vue.prototype.xyz=100;
// Vue.prototype.$EventBus=vm

new Vue({
  beforeCreate(){
  //安装事件总线
  Vue.prototype.abc=900;
  Vue.prototype.$EventBus=this
 },
  render: h => h(App),
}).$mount('#app')

2.2 向EventBus发送事件

img

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

已经创建好EventBus后我们就需要向它发送需要传递的事件,以便其他组件可以向EventBus获取。

例子:有两个组件A和B需要通信,他们不是父子组件关系,B事件需要获得A事件里的一组数据data

<!--  -->
<template>
  <div id="demo01">
    <h1>Demo01组件</h1>
    <h2>从Demo02接受的收据:{{msg}}</h2>
    <button @click="fasong">发送数据给Demo02</button>
  </div>
</template>

<script>
export default {
  name: "Demo01",
  data () {
    return {
      msg: ''
    }
  },
  methods: {
    test01 (data) {
      console.log(data);
      this.msg = data
    },
    fasong () {
      this.$EventBus.$emit("send", "我是Demo01页面");
    }
  },
  mounted () {
    // console.log(this);
    // 2.接受全局的haha事件
    this.$EventBus.$on('haha', this.test01)
  }
}
</script>
<style scoped>
#demo01 {
  background-color: red;
  padding: 20px;
  margin-bottom: 20px;
}
</style>

2.3 接受EventBus事件

img

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

A组件已经向全局事件总线EventBus发送了一个aMsg事件,这时B组件就可以去aMsg监听这个事件,并可以获得一些数据。

<!--  -->
<template>
  <div id="demo02">
    <h1>Demo02组件</h1>
    <button @click="sendData">发送事件给Demo01</button>
    <h2>从Demo01接受的收据:{{msg}}</h2>
  </div>
</template>

<script>
export default {
  name: "Demo02",
  data () {
    return {
      msg: ''
    }
  },
  methods: {
    sendData () {
      // 触发全局的haha事件
      this.$EventBus.$emit("haha", '老王')
    },
    display (data) {
      console.log(data);
      this.msg = data
    }
  },
  mounted () {
    // console.log(this.abc);
    console.log(this.$EventBus);
    this.$EventBus.$on("send", this.display)
  }
}
</script>
<style scoped>
#demo02 {
  background-color: blue;
  padding: 20px;
}
</style>
GIF 2021-7-11 21-04-42.gif

2.4 移除监听事件

img

虽然EventBus是一个很轻便的方法,任何数据都可以往里传,然后被别的组件获取,但是如果用不好,容易出现很严重的BUG,所以接下来我们就来讲解一下移除监听事件。

在上一个例子中,我们Demo02组件向事件总线发送了一个事件sendData并传递了参数'老王',然后Demo01组件对该事件进行了监听,并获取了传递过来的参数。但是,这时如果我们离开Demo01组件,然后再次进入Demo01组件时,又会触发一次对事件sendData的监听,这时时间总线里就有两个监听了,如果反复进入sendData组件多次,那么就会对sendData进行多次的监听。

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

  • ==解决办法:在组件离开,也就是被销毁前,将该监听事件给移除,以免下次再重复创建监听==
  • 语法:this.$EventBus.$off(要移除监听的事件名)
<!--  -->
<template>
  <div id="demo02">
    <h1>Demo02组件</h1>
    <button @click="sendData">发送事件给Demo01</button>
    <h2>从Demo01接受的收据:{{msg}}</h2>
  </div>
</template>

<script>
export default {
  name: "Demo02",
  data () {
    return {
      msg: ''
    }
  },
  methods: {
    sendData () {
      // 触发全局的haha事件
      this.$EventBus.$emit("haha", '老王')
    },
    display (data) {
      console.log(data);
      this.msg = data
    }
  },
  mounted () {
    // console.log(this.abc);
    console.log(this.$EventBus);
    this.$EventBus.$on("send", this.display)
  },
  beforeDestory () {
    //移除事件监听send
    this.$EventBus.off("send")
  }
}
</script>
<style scoped>
#demo02 {
  background-color: blue;
  padding: 20px;
}
</style>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,393评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,790评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,391评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,703评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,613评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,003评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,507评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,158评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,300评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,256评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,274评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,984评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,569评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,662评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,899评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,268评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,840评论 2 339

推荐阅读更多精彩内容