记一个坑:使用$emit和$on多次调用Vue方法的问题
November 08, 2023
1081
1、问题总结 :
vue3项目中使用mitt作为组件之间的通信,页面A中的onMounted生命周期里emit.on()监听事件,页面B(或JS文件)中调用时,多次调用了vue的方法。
bug复现:在该项目中多次进入页面A,然后使用emit触发监听的事件。
2、mitt的使用
引入
1
2
3import mitt from "mitt";
const emitter = mitt();
export default emitter;使用
1
2
3
4
5
6
7// 页面A
import emitter from "@/utils/emit";
onMounted(async () => {
emitter.on("refreshH5", getCompletionInfo);
});1
2
3
4
5
6// 页面B || 其他组件 || 其他js文件
import emitter from "@/utils/emit";
emitter.emit("refreshH5");总结:将mitt方法要做的事做个比喻,该库的作用好比一辆公交车,上面的东西任意取用(
$on
),如果你有什么信息需要传达出去也可以将至放在($emit
)车上;如果不想公开了也可以把它撤下来($off
)。1
2
3
4// 使用方法
$emit('eventName', argsobj); // 如果传两个参数,那么fn(res),res将是一个数组: argsobj1,argsobj2]
$on('eventName', fn);
$off('eventName', fn);
3、踩坑后,思路总结:
发现多次调用事件后,一直是在组件里去销毁事件,发现这样销毁并不彻底;相当于是进入A页面一次,emitter.on就被执行一次,相当于是造了一辆车,那么多次进入就相当于造了多辆一模一样的车(误区:我以为会覆盖),然后我在其他组件使用emitter.emit(一枚钥匙),然而这一枚钥匙启动了多辆车,事件执行了多次。
解决办法:
1
2
3
4
5// 页面销毁时必须删除事件处理程序
onBeforeUnmount(() => {
emitter.off("refreshH5", getCompletionInfo)
})
- 本文作者:wowangmouren
- 本文链接:https://wangwewntao.top/2023/11/08/wmr_27/index.html
- 版权声明:本博客所有文章均采用 BY-NC-SA 许可协议,转载请注明出处!