在单页应用中,在 A 页面中触发事件,然后在 B 页面中对这个事件进行响应是一个很常见的需求,那么当有这种需求的时候要怎么实现呢。有两种方案可以实现:
1. 使用 vuex 状态管理,当触发事件时,改变 vuex 中的状态,然后在需要响应事件的地方用 watch 监听这个状态,当状态改变时,响应事件。
2. 使用 eventBus 事件总线,当触发事件时,发送一个通知出去,在需要响应的地方接收这个通知,响应事件。

方案一使用起来略复杂,有些东西也不是很好处理,综合考虑下来还是采用方案二,方案二比较符合正常的思维方式,使用也较方便。

基本使用

在官方文档上,对 eventbus 的介绍很简单,基本就是一笔带过,这里就来说下基本的使用方法。

创建 EventBus
//新建一个 js 文件,写下如下代码就创建好了一个 eventbus,没错,就是这么简单
import Vue from 'vue'

export default new Vue;

在 main.js 中导入 eventbus ,然后将它挂载到 vue 的原型上,这样就可以全局调用了

import bus from './utils/eventBus'

Vue.prototype.bus = bus;
发送事件

在触发事件的地方发送事件

this.bus.$emit(this.$route.path);

$emit(),里面需要一个string 类型的事件名,我这里是用的当前路由的 path 作为事件名。

接收事件

事件已经发送,接下来只需要在需要接收事件的地方接收这个事件,然后对事件进行响应就可以了。

        this.bus.$on(this.$route.path,()=>{
                this.getData();
            })

接收事件的时候同样需要一个事件名,然后是一个函数来进行事件响应,我这里是调用了下获取数据的接口。

这样,整个事件从发送到接收并响应就完成,是不是很简单。

事件重复触发的问题

坑一

正当你开心的准备玩耍的时候却发现好像有哪里不对劲,怎么事件会重复触发了,而且每次切换过路由后,事件执行次数就会加一,这怎么行,假如用户非常频繁的切换页面,那事件执行次数不是会越来越多,到最后不是要爆炸。

一番搜索后终于找到了原因,原来这是因为我们的事件是全局的,它并不会随着组件的销毁而自动注销,需要我们手动调用注销方法来注销。知道了问题原因就好办了,我们可以在组件的 beforeDestroy ,或 destroy 生命周期中执行注销方法,手动注销事件。

        beforeDestroy() {
            //组件销毁前需要解绑事件。否则会出现重复触发事件的问题
            this.bus.$off(this.$route.path);
        },

这样就完成了事件的注销操作,可以注销掉当前事件。

坑二

你以为这样就可以好好玩耍了吗,NO,NO,NO。
虽然我们在生命周期中注销了事件,然而还是发现事件会多次执行,问题依旧在,那是什么原因呢?
经过打印日志后发现,问题出在事件名上面,由于我是用的 this. route.paththis. r o u t e . p a t h 作 为 事 件 名 , 在 注 销 的 时 候 也 是 想 当 然 的 用 t h i s . toure.path 作为注销事件名。观察日志后发现,在 beforeDestroy 中, this.$route.path 根本就不是我们发送和响应事件时候的路由了,而是将要跳转页面的路由。

这其实就是生命周期的问题了,在 beforeDestroy 和 destroy 生命周期中,用 this.$route.path 获取到的其实是下一个页面的 path ,注意这一点,问题即可解决。解决方案也很简单,就是在当前页面用一个变量将当前路由存下来,用这个变量作为事件名注销事件即可。

Logo

前往低代码交流专区

更多推荐