Vue-EventBus £神魔★判官ぃ 2023-10-02 20:21 25阅读 0赞 ### 前沿 ### vue组件非常常见的有父子组件通信,兄弟组件通信。而父子组件通信就很简单,父组件会通过 props 向下传数据给子组件,当子组件有事情要告诉父组件时会通过 $emit 事件告诉父组件。**如果1个页面里很多组件没有任何引入和被引入关系(不是父子关系),而他们大多都是同级关系,该如何通信?** ![在这里插入图片描述][0634741e35fe45a0963616df1b187a8f.png] 听说EventBus,或者说或多或少都了解过,**他可以在任何两个组件中进行传值,不局限于父子、祖孙或是兄弟组件**,也可以说他是一种发布——订阅的设计模式。 **注意:** 1. 只能在一个页面里会初始化的组件之间才能通信, 因为只有组件初始化后,他们之间才能看见对方,才能加载到EventBus里 2. 如果组件销毁后那么EventBus是无法操作销毁后组件内的信息 ,所以发布事件的组件一定要在监听事件的组件之后结束生命周期(被销毁),否则发布的时候就会报错, 3. 发布事件的时候,所对应的监听事件的组件必须存在并且已经初始化了 以上这些问题需要在开发的时候注意, 绝大部分场景基本不会出现上面的问题,所以放心使用,如果出现了那么就,依据我上面说的情况进行分析就能解决了 ### 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引入 #### import EventBus from '../EventBus' #### 使用Vue原型链引入 #### // 在 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,...)` * eventName 发布事件的名称, 要和监听事件的名称一致 * param给监听事件的方法传参 ### 使用案例 ### 我们在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') } ### EventBus的原理是什么? ### 废话少说,直接上代码,用 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 进行移除。 因为如果移除了,其他组件还在调用那么就悲剧了, 所以一定要分析好在哪里移除 ![在这里插入图片描述][241d60d901ab468c8532f2a2d4413093.gif] 点赞 -收藏-关注-便于以后复习和收到最新内容有其他问题在评论区讨论-或者私信我-收到会在第一时间回复感谢,配合,希望我的努力对你有帮助^\_^ 免责声明:本文部分素材来源于网络,版权归原创者所有,如存在文章/图片/音视频等使用不当的情况,请随时私信联系我。 [0634741e35fe45a0963616df1b187a8f.png]: https://img-blog.csdnimg.cn/0634741e35fe45a0963616df1b187a8f.png [241d60d901ab468c8532f2a2d4413093.gif]: https://img-blog.csdnimg.cn/241d60d901ab468c8532f2a2d4413093.gif
还没有评论,来说两句吧...