vue 关闭弹如何销毁子组件_vue中的eventBus会产生内存泄漏吗
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会产生内存泄漏吗相关推荐
- vue created 调用方法_vue中的eventBus会产生内存泄漏吗
eventBus是在vue中经常用来解决跨组件消息传递的问题,但对它的使用要特别注意,否则会产生很严重的后果. 引入 本文介绍了eventBus的实现原理,并介绍它如何在vue中使用,并举了一个具体的 ...
- vue请求数据传给子组件_vue.js基础,父组件如何向子组件传递数据「607」
本文只有一个学习点. 父组件如何向子组件传递数据. 一起学习,更多文章请关注我的头条号,我是落笔承冰. 一.先创建一张空白网页index.html,在head标签里设置好vue的链接库. 二.写一个绑 ...
- vue如何主动销毁子组件_Vue自动销毁的vue event Bus
我们通常在使用非父子组件间通信时,采用new Bus()的方式来做一个事件广播. 但一个弊端就是,这种方式并不会自动销毁,所以为了避免回调函数重复执行,还要在destroyed周期中去做Bus.$of ...
- vue使用ts 引入组件_vue中使用TS实现父子组件直接的通信
vue中使用ts 在vue中使用ts是需要有一定的ts基础的,如果对于ts小白的话还是推荐先看一下ts官网,先了解基础以后这样使用起来才会事半功倍. 1.下载依赖项 npm install --sav ...
- Vue父组件传子组件数据中,Vue监听不到数据改变
Vue父组件传子组件数据中,Vue监听不到数据改变 官方文档说明(引用来自官网) 检测变化的注意事项 由于 JavaScript 的限制,Vue 不能检测数组和对象的变化.尽管如此我们还是有一些办法来 ...
- vue中解决three.js出现内存泄漏丢失上下文问题
vue中解决three.js出现内存泄漏丢失上下文问题 参考文章: (1)vue中解决three.js出现内存泄漏丢失上下文问题 (2)https://www.cnblogs.com/lichuank ...
- vue 父组件获取接口值传到子组件_vue父组件异步获取数据传给子组件的方法
但是现在问题是父组件的数据是异步获取的,而子组件一开始就会渲染,如果此时没有传入数据,而子组件又要用到数据中的length属性时就会报错: 怎么办呢?最简单的办法就是让子组件条件渲染,当有数据的时候才 ...
- vue父组件变量传递子组件_Vue.js 父组件向子组件传递数据通过 props
我的使用场景:父组件:home.vue 子组件:feed-section.vue 父组件 home.vue 通过请求拿到数据后,传递给子组件 feed-section.vue:因为在子组件中需要渲染 ...
- vue 父组件获取接口值传到子组件_vue 项目中 “父组件” 异步获取数据之后,传递给子组件不显示...
有两个组件:一个为 transaction(父组件),一个为 transactionList (子组件): 上图为一个列表页,为父组件,在父组件里面的data中定义了数据列表, template中: ...
最新文章
- 2019年陕西高考分数线出炉
- python中的内置函数怎么学_python内部函数学习(九)
- videojs重播_vue2.0 vue-video-player 直播hls 回放mp4
- web-attack 1-5视频汇总
- 浙江新增python课程_今年9月起 浙江八年級新增Python編程課程
- PHP随机生成指定时间段的指定个数时间
- .Net CF 开发菜鸟笔记(PDA应用开发)
- 以太坊上海协议之——达成Cosmos网络实现以太坊扩容协议
- Hadoop集群配置(二)免密登录和集群配置
- 摆球控制程序PID算法
- 移植Linux Kernel SM750 驱动到VxWorks 7
- 主成分分析(PCA)的一种理解和推导
- 爬虫小程序 - 周杰伦歌曲
- 小学生计算机按键分布图,小学生计算器上各种按键的作用
- 推荐几个程序员Mac m1max芯片笔记本软件
- 带你了解什么是MySQL数据库(八)数据库锁机制
- Drupal漏洞复现:CVE-2019-6341
- win10系统打开更新服务器失败怎么回事,如何修复Windows Update组件以解决Win10无法自动更新的问题?...
- Supervisor的使用方法
- acme.sh使用阿里云DNS申请Let’s Encrypt的https证书
热门文章
- find vba 模糊_VBA积木代码方案:实现多重查找、模糊查找、清除值
- Ultra96_v2实现交通标示识别
- FPGA课程设计使用VHDL语言
- toft 测试用例rat_一篇文章详述配对测试的测试用例设计!强烈建议收藏
- 一种基于谷歌浏览器加载activex控件的解决方法与流程技术_Office控件使用总踩雷?畅写Office带你云端飞行...
- lin通信ldf文件解析_手把手教你在CANoe中创建一个LIN通讯工程
- python接口测试_Python接口自动化测试框架实战开发(一)
- linux vi删除操作,vi删除操作
- 在用户离开页面(刷新、后退、关闭等)时提示信息
- Ubuntu18.04安装Nautilus-actions自定义文件管理器鼠标右键列表