vue中的eventBus,

  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的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: