vue组件非常常见的有父子组件通信,兄弟组件通信。而父子组件通信就很简单,父组件会通过 props 向下传数据给子组件,当子组件有事情要告诉父组件时会通过 $emit 事件告诉父组件。如果1个页面里很多组件没有任何引入和被引入关系(不是父子关系),而他们大多都是同级关系,该如何通信?
听说EventBus,或者说或多或少都了解过,他可以在任何两个组件中进行传值,不局限于父子、祖孙或是兄弟组件,也可以说他是一种发布——订阅的设计模式。
注意:
以上这些问题需要在开发的时候注意, 绝大部分场景基本不会出现上面的问题,所以放心使用,如果出现了那么就,依据我上面说的情况进行分析就能解决了
EventBus 又称为事件总线。在Vue中可以使用 EventBus 来作为沟通桥梁的概念,就像是所有组件共用相同的事件中心,可以向该中心注册发送事件或接收事件,所以组件都可以上下平行地通知其他组件,但也就是太方便所以若使用不慎,就会造成难以维护的“灾难”,因此才需要更完善的Vuex作为状态管理中心,将通知的概念上升到共享状态层次。
Vue中自带EventBus,不需要额外任何使用插件 ,只需要new一个「vue实例」像这样~
创建一个EventBus.js文件
import Vue from 'vue' // 引入vue
const EventBus = new Vue() // 创建实例
export default EventBus // 导出
引入的方式有两种 ,任选其一 建议使用import方式
import EventBus from '../EventBus'
// 在 src 的 main.js 中,加上以下代码
// 引入第一步创建好的 EventBus
import EventBus from './EventBus'
// 这个方式可以在任何组件里直接用 this.$EventBus 调用
Vue.prototype.$EventBus = EventBus
// 也可以直接这样使用,不需要第一步的创建
// import Vue from 'vue'
// Vue.prototype.$EventBus = new Vue()
// 这种也行 但是使用的时候需要windows.eventBus 调用
//window.eventBus = new Vue();
下面教程我们就使用import方式引入的方式来演示
语法:
// eventName 是事件的名称 , param接收的参数
EventBus .$on('eventName', (param1,param2,...)=>{
//需要执行 逻辑代码
}
语法: EventBus .$emit('eventName', param1,param2,...)
我们在A组件面里, 将消息发给B组件
<!-- A.vue -->
<template>
<button @click="sendMsg()">-</button>
</template>
<script>
import { EventBus } from "../event-bus.js";
export default {
methods: {
sendMsg() {
EventBus.$emit("aMsg", '来自A页面的消息');
}
}
};
</script>
<!-- B.vue -->
<template>
<p>{{msg}}</p>
</template>
<script>
import { EventBus } from "../event-bus.js";
export default {
data(){
return {
msg: ''
}
},
mounted() { //组件初始时候加载
EventBus.$on("aMsg", (msg) => {
// A发送来的消息
this.msg = msg;
});
}
};
</script>
同理我们也可以在 B组件 向 A组件 发送消息或者操作A组件方法等…
在开发的过程中,我们要及时移除不使用的 eventBus ,原因:
① 为了避免在监听时,事件被反复触发
② 由于热更新,事件可能会被多次绑定监听,这时也需要移除事件监听
③ 未及时移除的 eventBus 会导致内存泄漏
语法: eventBus.$off('eventName');
//当前实例销毁之前调用
beforeDestroy () {
console.log('----A页面销毁监听事件----')
this.$EventBus.$off('getNum')
}
废话少说,直接上代码,用 class 来实现我们自己的 EventBus:
class MyEventBus {
constructor() {
// 存储所有事件对应的回调的对应关系
/**
* key : [ callback, callback ]
*/
this.items = {};
}
// 监听
$on(eventName, callback) {
if (!this.items[eventName]) {
//一个事件可能有多个监听者
this.items[eventName] = [];
}
this.items[eventName].push(callback)
// 简化版写法 等同于上面
// (this.items[eventName] ||= []).push(callback)
}
// 触发监听
$emit(eventName, ...args) {
if (!this.items[eventName]) return;
this.items[eventName].forEach(ca => ca(...args))
}
// 去掉监听
$off(eventName) {
this.items[eventName] = []
}
}
export default new MyEventBus();
就是我们在项目中可能会创建多个 eventBus.js 文件,而两个或者多个组件要使用 eventBus 进行通信时一定要使用同一个 eventBus.js 文件,否则会报错,我之前就遇到过,哈哈!
Vue中使用 eventBus 实现组件间的通信时,需要对 Bus.$emit()
、Bus.$on()
、Bus.$off()
或者其他 API 搭配使用。结合当前环境,判断是否有干扰项从而决定是否对 eventBus 进行移除。 因为如果移除了,其他组件还在调用那么就悲剧了, 所以一定要分析好在哪里移除
点赞 -收藏-关注-便于以后复习和收到最新内容有其他问题在评论区讨论-或者私信我-收到会在第一时间回复感谢,配合,希望我的努力对你有帮助^_^免责声明:本文部分素材来源于网络,版权归原创者所有,如存在文章/图片/音视频等使用不当的情况,请随时私信联系我。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://huanmin.blog.csdn.net/article/details/125770035
内容来源于网络,如有侵权,请联系作者删除!