在单页应用中,在 A 页面中触发事件,然后在 B 页面中对这个事件进行响应是一个很常见的需求,那么当有这种需求的时候要怎么实现呢。有两种方案可以实现:
方案一使用起来略复杂,有些东西也不是很好处理,综合考虑下来还是采用方案二,方案二比较符合正常的思维方式,使用也较方便。
在官方文档上,对 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);
},
这样就完成了事件的注销操作,可以注销掉当前事件。
虽然我们在生命周期中注销了事件,然而还是发现事件会多次执行,问题依旧在,那是什么原因呢?
经过打印日志后发现,问题出在事件名上面,由于我是用的 this.route.path作为事件名,在注销的时候也是想当然的用this.
toure.path 作为注销事件名。观察日志后发现,在 beforeDestroy 中, this.$route.path 根本就不是我们发送和响应事件时候的路由了,而是将要跳转页面的路由。
这其实就是生命周期的问题了,在 beforeDestroy 和 destroy 生命周期中,用 this.$route.path 获取到的其实是下一个页面的 path ,注意这一点,问题即可解决。解决方案也很简单,就是在当前页面用一个变量将当前路由存下来,用这个变量作为事件名注销事件即可。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。