手机版

Vue中使用的事件总线有一个生命周期

时间:2021-08-31 来源:互联网 编辑:宝哥软件园 浏览:

最近,我们在vue项目中遇到了性能问题。整个项目已经连续运行了五分钟左右,页面卡住了。查看页面占用1.5G内存。经过调查,部分原因是我们模块使用的eventBus在离开页面时没有关闭。让我们进行以下验证:

1、不随生命周期而破坏

我们主页上的代码是这样的:

created(){让text=array (1000000)。填充(' XXX ')。join(',')//创建一个大字符串来验证$ eventbus的内存使用情况。$ on ('home-on ',(.args)={this。text=text })Mounted(){ settimeout()={ $ event bus。$ emit ('home-on ','这是home $emit参数',' ee')},1000)},before destroy(){//注意没有关闭' home-on '的订阅事件}/。

图1

总共1740万m,我们创建的字符串文本占据了800万,在主页没有被破坏的情况下是正常的

(2)离开主页时:然后我们点击跳转到其他页面离开主页,然后拍一张内存快照:

图2

创建的字符串“xxx,XXX…”安装在主页上的this.text上,离开家后仍然存在。看下面的箭头,我们可以看到它存在于EventBus上。原因显而易见:我们在destroy之前没有销毁订阅的事件,但是EventBus是全局的,并且在订阅on的回调中调用了this.text,所以回调中的这个一直挂在EventBus中。

2.毁灭与生命周期

created(){让text=array (1000000)。填充(' XXX ')。join(',')//创建一个大字符串来验证$ eventbus的内存使用情况。$ on ('home-on ',(.args)={this。text=text })Mounted(){ settimeout(()={ $ event bus。$ emit ('home-on ','这是home $emit参数',' ee') },1000)},Before destroy () {$ eventbus。$ off(‘Home-On’)//注意这里‘Home-On’的订阅事件是off的} //eventBus是全局的(1)在主页上:不用说,内存快照自然就是图1中的内存快照。

(2)离开主页时:再拍一张内存快照:

发现缩小到10M,内存被‘XXX,XXX .’占用in' string '不再被占用,这表明浏览器在我们销毁它后回收了this.text。

好了,以上都只是说明了在使用EventBus的时候要时刻注意订阅事件的销毁。如果一个可以,如果有五六个.逐一销毁它们会很麻烦。据说“关”破坏了这种重复性的工作,本该由机器来完成,我们不应该在意。

基于以上所述,我们自然会想到让EventBus随着其生命周期一起被销毁。EventBus具有生命周期的特点,因此离不开这种使用的关联。$on,并且每个Vue组件都有自己的_uid作为唯一标识符,所以我们基于uid稍微修改了EventBus,这样EventBus和_uid就可以关联3360

类事件总线(构造函数(vue) { if(!这个。句柄){ object。definepreproperty(this,' handles ',{ value: {,可枚举: false })this .vue=vue这个。eventmapuid={ }//_ uid和事件名的映射} setEventMapUid (uid,eventName) { if(!这个。EventMapuid[uid])这个。event mapuid[uid]=[]这个。事件映射.push(eventName) //把每个_uid订阅的事件名字推到各自用户界面设计(用户界面设计的缩写)所属的数组里} $on (eventName,callback,vm) { //vm是在组件内部使用时组件当前的这用于取_uid if(!这个。处理[事件名称])。处理[事件名称]=[]这个。处理[事件名称].推(回调)if (vm instanceof this .Vue) this.setEventMapUid(vm ._uid,eventName)} $ emit(){//console。日志('事件总线发出事件名称==',事件名称)让args=[.参数]让事件名=args[0]让params=args。切片(1)如果(这个。处理[事件名称]){让len=this。处理[事件名称].长度为(设I=0;我透镜;i ) { this.handles[eventName][i](.params)} } } $ offVmEvent(uid){让CurrentEvents=this。EventMapuid[uid]| |[]CurrentEvents。foreach(event={ this .$off(事件)}) } $off(事件名称){删除这个。手柄[事件名称] }}//下面写成某视频剪辑软件插件形式,直接引入然后Vue.use($EventBus)进行使用让$ EventBus={ } $ EventBus。install=(Vue,option)={ Vue。原型。$ EventBus=new EventBus(Vue)Vue。mixin({ beforedtrol(){ this .$eventBus .$offVmEvent(这_uid) //拦截销毁前钩子自动销毁自身所有订阅的事件} })}导出默认$EventBus下面来进行使用

//main.js中.从""导入事件总线/EventBus。js ' vue。使用(EnMEtbus).组件中使用:

已创建(){ 0让文本=数组(1000000).填充(' xxx ').连接(',')这个$eventBus .$on('home-on ',(.args)={控制台。日志(' home $ on====',args) this.text=text },this) //注意第三个参数需要传当前组件的这个,如果不传则需要手动销毁},挂载(){ setTimeout(()={ this .$eventBus .$emit('home-on ','这是home $emit参数,' ee') },1000) },beforeDestroy () { //这里就不需要手动的离开销毁事件总线订阅的事件了}总结

以上所述是小编给大家介绍的某视频剪辑软件中使用的事件总线有生命周期,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

版权声明:Vue中使用的事件总线有一个生命周期是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。