文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

vue中的eventBus会产生内存泄漏吗

2023-06-29 03:29

关注

这篇文章主要介绍了vue中的eventBus会产生内存泄漏吗,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

eventBus是在vue中经常用来解决跨组件消息传递的问题,但对它的使用要特别注意,否则会产生很严重的后果。

引入

本文介绍了eventBus的实现原理,并介绍它如何在vue中使用,并举了一个具体的例子来说明,如果使用不当,它会造成内存泄漏。

要注意eventBus并不是前端的概念。

由greenrobot [1] 组织贡献(该组织还贡献了greenDAO),一个Android事件发布/订阅轻量级框架,

功能:通过解耦发布者和订阅者简化Android事件传递 [2]

EventBus可以代替Android传统的Intent,Handler,Broadcast或接口函数,在Fragment,Activity,Service线程之间传递数据,执行方法。

特点:代码简洁,是一种发布订阅设计模式(观察者设计模式)。

内容

eventBus在vue中的实现

eventBus是事件总线的意思,它本质上是一个发布订阅者实现,在vue2.X中,vue实例上提供了$on,$emit,$off这三个方法,分别用来添加观察者,发布事件,取消订阅这三个操作。

所以,我们可以直接把一个vue实例挂到Vue的原型上来充当组件相互通信的中介。

Vue.prototype.$eventBus = new Vue()

这样一来,所有的Vue组件都可以沿着原型链找到这个$eventBus,从而访问$on, $off,$emit。

它可以帮助我们实现跨组件的通信。

vue中的eventBus会产生内存泄漏吗

例子:使用eventBus

在根组件中发布事件,在两个子组件中去监听事件。

vue中的eventBus会产生内存泄漏吗

<div id="app">   <h3>eventBus的基本使用</h3>   <com1></com1>   <com2></com2> </div> <script>   Vue.prototype.$eventBus = new Vue()   Vue.component('com1', {     template:`<div>com1</div>`,     created () {       this.$eventBus.$on('event1', function f1(d){         conse.log(d, 'com1 listen...  event1')       })     },   })   Vue.component('com2', {     template:`<div>com2</div>`,     created () {       this.$eventBus.$on('event2', function f2(d) {         conse.log(d, 'com2 listen...  event2')       })     }   })   var vm = new Vue({     el: '#app',     created () {       setInterval( () => {         const d = Date.now()         this.$eventBus.$emit('event1', d)         this.$eventBus.$emit('event2', d)       }, 3000)     }   }) </script>

在创建com1组件时,订阅event1事件;在创建com2组件时,订阅event2事件;在创建根组件(vue实例)时,开启定时器:每隔3s发布事件,这样的话,com1和com2就都可以收到事件,并执行对应的回调。

效果如下:

vue中的eventBus会产生内存泄漏吗

例子:不及时取消订阅

如果不及时取消订阅,则回调函数仍会执行,更严重的是,如果在事件处理回调函数中引用了外部变量形成了闭包,则会导致内存泄漏。

下面的代码说明这个问题。

在根组件(vue实例)中,补充一个数据项showCom1,并配置v-if指令来实现销毁和重建com1组件。

<div id="app">   <h3>不及时取消订阅的问题</h3>   <button @click="showCom1=!showCom1">     {{showCom1 ? "销毁" : "重建"}}组件1   </button>   <com1 v-if="showCom1"></com1>   <com2></com2> </div> <script>   Vue.prototype.$eventBus = new Vue()   Vue.component('com1', {     template:`<div>com1</div>`,     created () {       conse.log('创建com1')       this.$eventBus.$on('event1', function f1(d) {         conse.log(d, 'com1 listen... event1')       })     }   })   Vue.component('com2', {     template:`<div>com2</div>`,     created () {       this.$eventBus.$on('event2', function f2(d) {         conse.log(d, 'com2 listen... event2')       })     }   })   var vm = new Vue({     el: '#app',     data:{       showCom1: true     },     created () {       setInterval( () => {         const d = Date.now()         this.$eventBus.$emit('event1', d)         this.$eventBus.$emit('event2', d)       }, 3000)     }   }) </script>

先提一个问题:你觉得com1组件被销毁后,它在created中订阅的event1事件还能再收到吗?对应的回调函数还能再执行吗?一般的想法是组件都销毁了,那它订阅的事件肯定也收不到了嘛

答案是:还能收到。原因很简单:事件订阅这功能是$eventBus对象完成的,与这个com1组件无关。

上面的代码执行的效果,是这样的:

vue中的eventBus会产生内存泄漏吗

下面再来说明内存泄漏的问题,把com1的组件内容改成如下:

 Vue.component('com1', {   template:`<div>com1</div>`,   created () {     console.log('创建com1')     let m = 1*1024 * 1024     let arr = new Array(m).fill('a')      this.$eventBus.$on('event1', function f1(d) {       // 注意这里有一个闭包       console.log(d, 'com1 listen... event1', arr[1])    })  } })

在回调函数f1中引用函数之外的变量arr,这里有一个闭包。

下面在浏览器的调试工具中的memory添加一个快照,查看结果如下:

vue中的eventBus会产生内存泄漏吗

然后,点击页面上的“销毁组件1”,再次添加一个快照,你会发现这个空间并没有释放掉。

解释如下:

vue中的eventBus会产生内存泄漏吗

上面是这个过程的示意图,由于没有及时取消订阅f1,所以arr这个数组并没有释放掉。

解决方案:

在com1的destoryed钩子中,调用$off来取消订阅。

destroyed () {   // 取消所有对event1事件的监听   this.$eventBus.$off('event1') }

调试结果如下:

可见,com1删除之后,这个数值的空间释放掉了,同时它的事件监听函数也不会再执行了。

其它注意事项

$off的格式:

父子组件的created和mounted的区别, 按执行顺序:

所以,到底在哪个钩子中订阅,在哪个钩子中发布,要根据情况来定。

感谢你能够认真阅读完这篇文章,希望小编分享的“vue中的eventBus会产生内存泄漏吗”这篇文章对大家有帮助,同时也希望大家多多支持编程网,关注编程网行业资讯频道,更多相关知识等着你来学习!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯