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

引入

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

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

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

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

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

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

摘自百度百科。https://baike.baidu.com/item/EventBus/20461274?fr=aladdin

内容

  • eventBus在vue中的实现;
  • 在vue使用eventBus;
  • 使用不当的问题:多次执行回调;内存泄漏;
  • 解决方案:及时调用$off

eventBus在vue中的实现

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

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

 Vue.prototype.$eventBus = new Vue()

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

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

例子:使用eventBus

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

 
   

eventBus的基本使用

       

 

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

效果如下:

例子:不及时取消订阅

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

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

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

 
   

不及时取消订阅的问题

       {{showCom1 ? "销毁" : "重建"}}组件1          

 

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

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

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

  • 销毁组件1之后,它还能正常收到event1事件,并执行回调;
  • 再次创建组件1后,它会再次订阅event1事件,所以结果是执行两次回调。

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

 Vue.component('com1', {   template:`
com1

`,   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添加一个快照,查看结果如下:

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

解释如下:

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

解决方案:

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

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

调试结果如下:

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

其它注意事项

$off的格式:

  • $off() 会取消所有的事件订阅;
  • $off('事件名') 会取消指定事件名的;
  • $off('事件名', 回调) 会取消指定事件名的,指定回调

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

  • 父组件的created 先于子组件的created
  • 父组件的mounted先于子组件的mounted

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

小结

eventBus是一个名词,并非前端独有;

new Vue() 得到的实例上已经实现了发布订阅模式,可以直接做eventBus使用;

使用eventBus要及时调用$off;

vue 关闭弹如何销毁子组件_vue中的eventBus会产生内存泄漏吗相关推荐

  1. vue created 调用方法_vue中的eventBus会产生内存泄漏吗

    eventBus是在vue中经常用来解决跨组件消息传递的问题,但对它的使用要特别注意,否则会产生很严重的后果. 引入 本文介绍了eventBus的实现原理,并介绍它如何在vue中使用,并举了一个具体的 ...

  2. vue请求数据传给子组件_vue.js基础,父组件如何向子组件传递数据「607」

    本文只有一个学习点. 父组件如何向子组件传递数据. 一起学习,更多文章请关注我的头条号,我是落笔承冰. 一.先创建一张空白网页index.html,在head标签里设置好vue的链接库. 二.写一个绑 ...

  3. vue如何主动销毁子组件_Vue自动销毁的vue event Bus

    我们通常在使用非父子组件间通信时,采用new Bus()的方式来做一个事件广播. 但一个弊端就是,这种方式并不会自动销毁,所以为了避免回调函数重复执行,还要在destroyed周期中去做Bus.$of ...

  4. vue使用ts 引入组件_vue中使用TS实现父子组件直接的通信

    vue中使用ts 在vue中使用ts是需要有一定的ts基础的,如果对于ts小白的话还是推荐先看一下ts官网,先了解基础以后这样使用起来才会事半功倍. 1.下载依赖项 npm install --sav ...

  5. Vue父组件传子组件数据中,Vue监听不到数据改变

    Vue父组件传子组件数据中,Vue监听不到数据改变 官方文档说明(引用来自官网) 检测变化的注意事项 由于 JavaScript 的限制,Vue 不能检测数组和对象的变化.尽管如此我们还是有一些办法来 ...

  6. vue中解决three.js出现内存泄漏丢失上下文问题

    vue中解决three.js出现内存泄漏丢失上下文问题 参考文章: (1)vue中解决three.js出现内存泄漏丢失上下文问题 (2)https://www.cnblogs.com/lichuank ...

  7. vue 父组件获取接口值传到子组件_vue父组件异步获取数据传给子组件的方法

    但是现在问题是父组件的数据是异步获取的,而子组件一开始就会渲染,如果此时没有传入数据,而子组件又要用到数据中的length属性时就会报错: 怎么办呢?最简单的办法就是让子组件条件渲染,当有数据的时候才 ...

  8. vue父组件变量传递子组件_Vue.js 父组件向子组件传递数据通过 props

    我的使用场景:父组件:home.vue 子组件:feed-section.vue 父组件 home.vue 通过请求拿到数据后,传递给子组件 feed-section.vue:因为在子组件中需要渲染 ...

  9. vue 父组件获取接口值传到子组件_vue 项目中 “父组件” 异步获取数据之后,传递给子组件不显示...

    有两个组件:一个为 transaction(父组件),一个为 transactionList (子组件): 上图为一个列表页,为父组件,在父组件里面的data中定义了数据列表, template中: ...

最新文章

  1. 2019年陕西高考分数线出炉
  2. python中的内置函数怎么学_python内部函数学习(九)
  3. videojs重播_vue2.0 vue-video-player 直播hls 回放mp4
  4. web-attack 1-5视频汇总
  5. 浙江新增python课程_今年9月起 浙江八年級新增Python編程課程
  6. PHP随机生成指定时间段的指定个数时间
  7. .Net CF 开发菜鸟笔记(PDA应用开发)
  8. 以太坊上海协议之——达成Cosmos网络实现以太坊扩容协议
  9. Hadoop集群配置(二)免密登录和集群配置
  10. 摆球控制程序PID算法
  11. 移植Linux Kernel SM750 驱动到VxWorks 7
  12. 主成分分析(PCA)的一种理解和推导
  13. 爬虫小程序 - 周杰伦歌曲
  14. 小学生计算机按键分布图,小学生计算器上各种按键的作用
  15. 推荐几个程序员Mac m1max芯片笔记本软件
  16. 带你了解什么是MySQL数据库(八)数据库锁机制
  17. Drupal漏洞复现:CVE-2019-6341
  18. win10系统打开更新服务器失败怎么回事,如何修复Windows Update组件以解决Win10无法自动更新的问题?...
  19. Supervisor的使用方法
  20. acme.sh使用阿里云DNS申请Let’s Encrypt的https证书

热门文章

  1. find vba 模糊_VBA积木代码方案:实现多重查找、模糊查找、清除值
  2. Ultra96_v2实现交通标示识别
  3. FPGA课程设计使用VHDL语言
  4. toft 测试用例rat_一篇文章详述配对测试的测试用例设计!强烈建议收藏
  5. 一种基于谷歌浏览器加载activex控件的解决方法与流程技术_Office控件使用总踩雷?畅写Office带你云端飞行...
  6. lin通信ldf文件解析_手把手教你在CANoe中创建一个LIN通讯工程
  7. python接口测试_Python接口自动化测试框架实战开发(一)
  8. linux vi删除操作,vi删除操作
  9. 在用户离开页面(刷新、后退、关闭等)时提示信息
  10. Ubuntu18.04安装Nautilus-actions自定义文件管理器鼠标右键列表