Vue 单页面应用中,不要在 onMount 里添加事件监听器!

大家好,我是宝哥。

在开发Vue单页面应用时,我们经常会遇到需要在组件中添加事件监听器的情况。然而,如果不正确地管理这些监听器,就可能引发一些棘手的问题,比如事件触发次数异常增加。本文将分享一次我在项目中遇到的事件监听器堆叠问题,以及我是如何通过几种策略来解决这个问题的。

46d34688e648a94b170f13ffdebae10f.jpeg

本周我会分享下面一系列的Vue教程,欢迎关注我。

引言

最近在为客户做一个项目时,需要在基于 Vue  的单页面应用  (SPA)  中集成一个事件监听器,该事件监听器用于一个名为  "HomeView"  的组件,该组件包含一个  iframe。这个事件,名为  "triggerEvent",最初是在  HomeView  的  onMount  生命周期钩子中设置的。这种设置会导致一个意想不到的行为:当你离开  HomeView  然后返回时,"triggerEvent"  会触发多次,表明事件监听器在堆叠。

问题分析

为了更好地理解这个问题,我尝试使用  location.replace()  而不是  router.push()  来进行导航。前者似乎解决了问题,这表明导航方法会影响事件监听器的行为。进一步测试  router.push()  证实,每次导航都会添加一个新的监听器,而不会移除之前的监听器,从而导致触发次数不断增加。

根本原因

这种行为源于像  Vue  这样的  SPA  框架如何管理事件监听器。在 Vue  中,使用  onMount  挂载的组件,在卸载时不会自动清理其事件监听器,除非在代码中显式地进行清理。因此,如果一个组件多次挂载,就像在  SPA  中使用  router.push()  进行导航(不进行完整的页面重新加载)时常见的情况,就会导致监听器重复。

解决方案

组件卸载时清理监听器

为了防止此问题,一个有效的策略是在组件卸载时移除事件监听器:

<template>
 <!-- Your component template -->
</template>

<script> import { onMounted, onUnmounted } from 'vue';

export default {
 setup() {
   const handleEvent = () => console.log('Event triggered');
   onMounted(() => window.addEventListener('triggerEvent', handleEvent));
   onUnmounted(() => window.removeEventListener('triggerEvent', handleEvent));
 }
}; </script>`

条件事件监听器绑定

另一种方法是在添加新的监听器之前检查是否已存在监听器,从而防止重复:

<template>
 <!-- Your component template -->
</template>

<script> import { onMounted, ref } from 'vue';

const eventBound = ref(false);

export default {
 setup() {
   const handleEvent = () => console.log('Event triggered');
   onMounted(() => {
     if (!eventBound.value) {
       window.addEventListener('triggerEvent', handleEvent);
       eventBound.value = true;
     }
   });
 }
}; </script>`

在  App.vue  中添加全局事件监听器

另一种方法是将事件监听器放在  App.vue  中,该组件只挂载一次,从而避免任何重新绑定问题:

<template>
 <div id="app">
   <!-- Your app template -->
 </div>
</template>

<script> import { onMounted } from 'vue';

export default {
 setup() {
   const handleEvent = () => console.log('Global event triggered');
   onMounted(() => window.addEventListener('triggerEvent', handleEvent));
 }
}; </script>`

总结

通过上述的探索和实践,我们可以看到,正确地管理事件监听器对于保持Vue单页面应用的稳定性和性能至关重要。无论是在组件卸载时进行清理,还是在添加之前检查监听器是否已存在,或是将监听器放在全局的App.vue中,这些策略都能有效地避免事件监听器的堆叠问题。希望这些经验能够帮助你在未来的Vue开发中避免类似的问题,让你的应用更加健壮和高效。


往期文章推荐


最后,如果你觉得宝哥的分享还算实在,就给我点个赞,关注一波。分享出去,也许你的转发能给别人带来一点启发。

关注下方宝哥微信,进宝哥前端开发11群,

获取我公众号整理的所有资料,

包括前端电子书,面试资料,简历模板和副业资料等!

7c31eedc73d33cf6e3861d28ff3cdbb9.png

添加好友备注【加群】拉你进技术交流群

公众号前端开发博客 专注 前端开发技术,分享 前端开发资源WEB前沿资讯,如果喜欢我的分享,给 宝哥 点一个 或者 分享 都是对我的支持

点击底部「阅读原文」跳转飞书文档(加入微信群)

以上,如果本文对你有所启发,欢迎点“45cb7d380f2c8ea614eb30b867ef2a46.gif在看、点赞”支持下吧! 

  • 26
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值