vue中的eventBus,
本文主要详细介绍vue中的eventBus是否会造成内存泄漏。本文中的示例代码非常详细,具有一定的参考价值。感兴趣的朋友可以参考一下,希望能帮到你。
目录
vue中eventBus的介绍示例:使用eventBus示例:及时退订其他注意事项总结eventBus在vue中经常被用来解决跨组件的消息传递问题,但是要特别注意它的使用,否则会产生严重的后果。
引入
本文介绍了eventBus的实现原理以及如何在vue中使用,并通过一个具体的例子说明如果使用不当,会造成内存泄漏。
注意,eventBus不是一个前端概念。
由greenrobot [1]贡献(组织也贡献了greenDAO),一个发布/订阅Android事件的轻量级框架,
功能:通过分离发布者和订阅者来简化Android事件交付[2]
EventBus可以替代Android传统的意图、处理程序、广播或接口功能,在片段、活动、服务的线程间传递数据和执行方法。
特点:代码简洁,是一种发布-订阅设计模式(观察者设计模式)。
内容
在vue中实现eventBus:在vue中使用event bus;使用不当:多次回调;内存泄漏;解决办法:及时叫停美元
eventBus在vue中的实现
EventBus的意思是事件总线,本质上是一个发布订阅者实现。在vue2。x,vue实例提供了三个方法:$ on,$ emit和$ off,分别用于添加观察者,发布事件和取消订阅。
因此,我们可以直接将一个vue实例附加到Vue的原型上,作为组件相互通信的中介。
Vue.prototype.$eventBus=new Vue()
这样,所有的Vue组件都可以沿着原型链找到这个$eventBus,从而访问$on,$off,$emit。
它可以帮助我们实现跨组件通信。
例子:使用eventBus
在根组件中发布事件,并在两个子组件中监听事件。
div id=应用程序
h2eventBus /h2的H2基本用法
com1/com1
com2/com2
/div
脚本
Vue.prototype.$eventBus=new Vue()
Vue.component(com1 ,{
模板:` divcom1/div `,
已创建(){
这个。$eventBus。$on(事件1 ,函数f1(d){
conse.log(d, com1听.事件1’)
})
},
})
Vue.component(com2 ,{
模板:` divcom2/div `,
已创建(){
这个。$eventBus。$on(事件2 ,函数f2(d) {
conse.log(d, com2听.事件2’)
})
}
})
var vm=new Vue({
埃尔: #app ,
已创建(){
setInterval( ()={
const d=Date.now()
这个。$eventBus。$emit(event1 ,d)
这个。$eventBus。$emit(event2 ,d)
}, 3000)
}
})
/脚本
创建com1组件时订阅event1事件;创建com2组件时订阅event2事件;创建根组件(vue实例)时,启动定时器:每3s发布一次事件,这样com1和com2都可以接收到事件并执行相应的回调。
效果如下:
例子:不及时取消订阅
如果不及时取消订阅,回拨功能仍会执行。更严重的是,如果在事件处理回调函数中引用外部变量形成闭包,会导致内存泄漏。
下面的代码说明了这个问题。
在根组件(vue实例)中,添加一个数据项showcom1,并配置v-if指令来销毁和重建com1组件。
div id=应用程序
H2没有及时取消订阅的问题/h2
button @click=showCom1=! showCom1
{{showCom1?销毁:重建 }}组件1
/按钮
com1 v-if=showCom1/com1
com2/com2
/div
脚本
Vue.prototype.$eventBus=new Vue()
Vue.component(com1 ,{
模板:` divcom1/div `,
已创建(){
Conse.log(创建com1 )
这个。$eventBus。$on(事件1 ,函数f1(d) {
conse.log(d, com1听.事件1’)
})
}
})
Vue.component(com2 ,{
模板:` divcom2/div `,
已创建(){
这个。$eventBus。$on(事件2 ,函数f2(d) {
conse.log(d, com2听.事件2’)
})
}
})
var vm=new Vue({
埃尔: #app ,
数据:{
真的
},
已创建(){
setInterval( ()={
const d=Date.now()
这个。$eventBus。$emit(event1 ,d)
这个。$eventBus。$emit(event2 ,d)
}, 3000)
}
})
/脚本
先问你一个问题:你觉得com1组件被破坏后,它在created订阅的event1事件还能再收到吗?对应的回调函数可以再次执行吗?大意是组件被销毁了,那么它订阅的事件肯定收不到。
答案是:还能收到。原因很简单:事件订阅功能是由$eventBus对象完成的,与这个com1组件无关。
上述代码执行的效果如下:
销毁组件1后,可以正常接收event1事件并执行回调;再次创建组件1后,它将再次订阅event1事件,因此结果是执行两个回调。
接下来,我们来解释一下内存泄漏的问题,将com1的组件内容改为如下:
Vue.component(com1 ,{
模板:` divcom1/div `,
已创建(){
Console.log(创建com1 )
设m=1*1024 * 1024
设arr=新数组(m)。填充(“a”)
这个。$eventBus。$on(事件1 ,函数f1(d) {
//注意这里有一个闭包
console.log(d, com1监听.事件1 ,arr[1])
})
}
})
回调函数f1中引用了函数外的变量arr,这里有一个闭包。
在下面的浏览器调试工具中将快照添加到内存中,并按如下方式检查结果:
然后,单击页面上的“销毁组件1”并再次添加快照。你会发现这个空间并没有被释放。
解释如下:
以上是这个过程的示意图。由于f1没有及时退订,数组arr没有释放。
解决方案:
在com1的destoryed钩子中,调用$off取消订阅。
销毁(){
//取消对event1事件的所有监控
这个。$eventBus。$off(事件1 )
}
调试结果如下:
可以看到,删除com1后,这个值的空间被释放,它的事件监控功能不会再被执行。
其它注意事项
$off的格式:
$off()将取消所有活动订阅;$off(事件名称)将取消事件名称的指定;$off (event name ,callback)将取消指定的事件名称,并按执行顺序指定回调的父子组件的创建和安装之间的差异:
父组件的创建先于子组件的创建,父组件的安装先于子组件的安装。所以要看哪个hook订阅发布的情况。
总结
EventBus是名词,不是前端特有的;
new Vue()获取的实例已经实现了发布订阅模式,可以直接作为eventBus使用;
使用eventBus及时调用$ off
本文到此为止。希望能帮到你,也希望你能多关注我们的更多内容!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。