Vue--事件总线
原文网址:Vue—事件总线_IT利刃出鞘的博客-CSDN博客
其他网址
Vue事件总线(EventBus)使用详细介绍 - 知乎
vue 事件总线EventBus的概念、使用以及注意点 - 简书
简易使用Vue中的中央事件总线(eventBus)
API — Vue.js 事件
简介
父子组件通信与兄弟组件通信
vue组件非常常见的有父子组件通信,兄弟组件通信。
父子组件通信:方法有很多,比如:父组件通过 props 向下传数据给子组件,子组件通过 $emit 告诉父组件。更多方法见:Vue基础系列—双向绑定_feiying0canglang的博客-CSDN博客
兄弟组件通信:如果两个页面没有任何引入和被引入关系,需要额外的组件来通信,如:事件总线、Vuex
事件总线概述
EventBus 又称为事件总线。在Vue中可以使用 EventBus 来作为沟通桥梁的概念,就像是所有组件共用相同的事件中心,可以向该中心注册发送事件或接收事件,所以组件都可以上下平行地通知其他组件。
EventBus若使用不慎,就会造成难以维护的“灾难”,因此才需要更完善的Vuex作为状态管理中心,将通知的概念上升到共享状态层次。
优点
- 解决了多层组件之间繁琐的事件传播。
- 使用原理十分简单,代码量少
缺点
- 大家都知道vue是单页应用,如果你在某一个页面刷新了之后,与之相关的EventBus会被移除,这样就导致业务走不下去。
- 如果业务有反复操作的页面,EventBus在监听的时候就会触发很多次,也是一个非常大的隐患。这时候我们就需要好好处理EventBus在项目中的关系。通常在vue页面销毁时,同时移除EventBus事件监听。
- 由于是都使用一个Vue实例,所以容易出现重复触发的情景:两个页面都定义了同一个事件名,并且没有用$off销毁(常出现在路由切换时)。
详述
创建事件
首先需要创建事件总线并将其导出,以便其它模块可以使用或者监听它。
法1、非全局事件组件
新建EventBus.js
import Vue from 'vue'
export const EventBus = new Vue()
法2、全局事件组件
在项目中的 main.js 初始化 EventBus。在main.js添加如下一行:
Vue.prototype.$EventBus = new Vue()
示例:
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
Vue.config.productionTip = false
Vue.prototype.$EventBus = new Vue();
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
用法
组件发送事件:this.$EventBus.$emit(…)
组件发送事件:this.$EventBus.$emit(…)下边这样写是不可以的
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
Vue.config.productionTip = false
let EventBus = new Vue();
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
EventBus,
components: { App },
template: '<App/>'
})
移除事件
一般在销毁组件(也就是离开组件)时移除事件。
beforeDestroy(){
EventBus.$off("eventName")
}
移除的方法
EventBus.$off() //移除EventBus所有事件监听器
EventBus.$off(‘eventName’) //移除’eventName’事件所有监听器
EventBus.$off(‘eventName’, callback) //只移除这个回调的监听器。
实例
本文父组件:CompA.vue,子组件1:ChildOne.vue,子组件2:ChildTwo.vue。子组件1发送事件给父组件和子组件2。
router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import CompA from "@/components/CompA";
Vue.use(Router)
export default new Router({
routes: [
{
path: '/compA',
name: 'compA',
component: CompA,
}
],
})
1.创建EventBus
新建EventBus.js
import Vue from 'vue'
export const EventBus = new Vue()
2.发送事件
components/ChildOne.vue
<template>
<div class="childOne">
<h1>childOne</h1>
<button @click="sendEvent2CompA">发送事件给父组件(CompA)</button>
<button @click="sendEvent2ChildTwo">发送事件给兄弟组件(ChildTwo)</button>
</div>
</template>
<script>
import {EventBus} from "./EventBus"
export default {
data() {
return {
count1: 0,
count2: 0,
}
},
methods:{
sendEvent2CompA() {
this.count1++;
EventBus.$emit("compA", "compA事件触发次数:" + this.count1)
},sendEvent2ChildTwo() {
this.count2++;
EventBus.$emit("childTwo", "childTwo事件触发次数:" + this.count2)
}
}
}
</script>
<style scoped>
</style>
3.接收事件
父组件:components/CompA.vue
<template>
<div class="compA">
<h1>compA</h1>
compA收到的事件内容:{
{msg}}<hr>
<child-one></child-one><hr>
<child-two></child-two>
</div>
</template>
<script>
import {EventBus} from "./EventBus"
import ChildOne from "@/components/ChildOne";
import ChildTwo from "@/components/ChildTwo";
export default {
components: {ChildOne, ChildTwo},
data() {
return {
msg: "",
}
},
mounted() {
EventBus.$on("compA", (payload1)=> {
this.msg = payload1;
})
}
}
</script>
<style scoped>
</style>
子组件2:components/ChildTwo.vue
<template>
<div class="childTwo">
<h1>childTwo</h1>
childTwo收到的事件内容:{
{msg}}
</div>
</template>
<script>
import {EventBus} from "./EventBus"
export default {
data() {
return {
msg: "",
}
},
mounted() {
EventBus.$on("childTwo", (payload1)=> {
this.msg = payload1;
})
}
}
</script>
<style scoped>
</style>
4.销毁事件
本处省略先不写。
5.测试
访问:http://localhost:8080/#/compA
还没有评论,来说两句吧...