Vue 中全局事件处理的传统做法
- 先创建一个名为
eventBus
的全局Vue
实例。
const eventBus = new Vue();
export default eventBus;
复制代码
- 在 Vue 组件中使用时,一般在
mounted
生命周期中注册事件处理函数。在destroyed
生命周期函数中解除注册的事件以免造成内存泄漏。
import { Component, Prop, Vue } from "vue-property-decorator";
import eventBus from "@/services/eventBus";
@Component
export default class HelloWorld extends Vue {
mounted(){
eventBus.$on(AppEvents.userInfoDidChanged, this.onUserInfoChanged);
}
onUserInfoChanged(){
}
destroyed(){
eventBus.$off(AppEvents.userInfoDidChanged, this.onUserInfoChanged);
}
}
复制代码
这样使用起来颇为繁琐。注册了某一个事件之后,必须在适用的时候取消注册。
使用 vue-geventbus
之后
这里要介绍的 Vue 插件 vue-geventbus 可以帮我们优雅的解决此问题。 在使用了 vue-geventbus
之后。后面我们写全局事件的注册函数就可以像下面这样写了。
this.$gon(AppEvents.userInfoDidChanged, () => {
});
复制代码
vue-geventbus
插件会在此 Vue 实例销毁时自动将此实例注册的全局事件处理函数全部清理以避免内存泄漏。
注意这里使用的是 vue-geventbus
插件添加的扩展方法 $gon
比 $on
多了一个 g
,就像 LOVE 去掉一半变 LOLI(这都啥跟啥啊?)
原理
具体来说是通过 Vue 的 Mixin 机制,为 Vue 组件添加了如下 mixin
vueClass.mixin({
destroyed() {
const vue = this as any;
clazz.removeListenersByVue(vue);
}
});
复制代码
也就是在 Vue
组件实例销毁时将此组件注册的所有事件处理函数清理掉。 后面的整个插件的代码都是为了实现此逻辑而来的。
事实上 vue-geventbus
重新实现了基本的 Vue
事件处理逻辑。下面的两者的事件对照表,也就是说 vue-geventbus
提供了 Vue 事件处理函数的全局事件处理函数的版本。
Vue Api | vue-geventbus Api |
---|---|
$on | $gon |
$once | $gonce |
$emit | $gemit |
$off | $goff |
本插件测试完善,也可以通过测试代码更多了了解本插件的一些特性细节。详情见参考仓库中的源代码。