日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > vue >内容正文

vue

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

發(fā)布時間:2023/12/15 vue 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 vue 关闭弹如何销毁子组件_vue中的eventBus会产生内存泄漏吗 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

eventBus是在vue中經(jīng)常用來解決跨組件消息傳遞的問題,但對它的使用要特別注意,否則會產(chǎn)生很嚴重的后果。

引入

本文介紹了eventBus的實現(xiàn)原理,并介紹它如何在vue中使用,并舉了一個具體的例子來說明,如果使用不當,它會造成內(nèi)存泄漏。

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

由greenrobot [1] 組織貢獻(該組織還貢獻了greenDAO),一個Android事件發(fā)布/訂閱輕量級框架,

功能:通過解耦發(fā)布者和訂閱者簡化Android事件傳遞 [2]

EventBus可以代替Android傳統(tǒng)的Intent,Handler,Broadcast或接口函數(shù),在Fragment,Activity,Service線程之間傳遞數(shù)據(jù),執(zhí)行方法。

特點:代碼簡潔,是一種發(fā)布訂閱設(shè)計模式(觀察者設(shè)計模式)。

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

內(nèi)容

  • eventBus在vue中的實現(xiàn);
  • 在vue使用eventBus;
  • 使用不當?shù)膯栴}:多次執(zhí)行回調(diào);內(nèi)存泄漏;
  • 解決方案:及時調(diào)用$off

eventBus在vue中的實現(xiàn)

eventBus是事件總線的意思,它本質(zhì)上是一個發(fā)布訂閱者實現(xiàn),在vue2.X中,vue實例上提供了$on,$emit,$off這三個方法,分別用來添加觀察者,發(fā)布事件,取消訂閱這三個操作。

所以,我們可以直接把一個vue實例掛到Vue的原型上來充當組件相互通信的中介。

?Vue.prototype.$eventBus?=?new?Vue()

這樣一來,所有的Vue組件都可以沿著原型鏈找到這個$eventBus,從而訪問$on, $off,$emit。

它可以幫助我們實現(xiàn)跨組件的通信。

例子:使用eventBus

在根組件中發(fā)布事件,在兩個子組件中去監(jiān)聽事件。

????

eventBus的基本使用

????????

在創(chuàng)建com1組件時,訂閱event1事件;在創(chuàng)建com2組件時,訂閱event2事件;在創(chuàng)建根組件(vue實例)時,開啟定時器:每隔3s發(fā)布事件,這樣的話,com1和com2就都可以收到事件,并執(zhí)行對應的回調(diào)。

效果如下:

例子:不及時取消訂閱

如果不及時取消訂閱,則回調(diào)函數(shù)仍會執(zhí)行,更嚴重的是,如果在事件處理回調(diào)函數(shù)中引用了外部變量形成了閉包,則會導致內(nèi)存泄漏。

下面的代碼說明這個問題。

在根組件(vue實例)中,補充一個數(shù)據(jù)項showCom1,并配置v-if指令來實現(xiàn)銷毀和重建com1組件。

????

不及時取消訂閱的問題

?????? {{showCom1 ? "銷毀" : "重建"}}組件1???????????

先提一個問題:你覺得com1組件被銷毀后,它在created中訂閱的event1事件還能再收到嗎?對應的回調(diào)函數(shù)還能再執(zhí)行嗎?一般的想法是組件都銷毀了,那它訂閱的事件肯定也收不到了嘛。

答案是:還能收到。原因很簡單:事件訂閱這功能是$eventBus對象完成的,與這個com1組件無關(guān)。

上面的代碼執(zhí)行的效果,是這樣的:

  • 銷毀組件1之后,它還能正常收到event1事件,并執(zhí)行回調(diào);
  • 再次創(chuàng)建組件1后,它會再次訂閱event1事件,所以結(jié)果是執(zhí)行兩次回調(diào)。

下面再來說明內(nèi)存泄漏的問題,把com1的組件內(nèi)容改成如下:

?Vue.component('com1', {???template:`com1`,???created?() {??? ?console.log('創(chuàng)建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])??? })??}?})

在回調(diào)函數(shù)f1中引用函數(shù)之外的變量arr,這里有一個閉包。

下面在瀏覽器的調(diào)試工具中的memory添加一個快照,查看結(jié)果如下:

然后,點擊頁面上的“銷毀組件1”,再次添加一個快照,你會發(fā)現(xiàn)這個空間并沒有釋放掉。

解釋如下:

上面是這個過程的示意圖,由于沒有及時取消訂閱f1,所以arr這個數(shù)組并沒有釋放掉。

解決方案:

在com1的destoryed鉤子中,調(diào)用$off來取消訂閱。

?destroyed?() {???// 取消所有對event1事件的監(jiān)聽???this.$eventBus.$off('event1')?}

調(diào)試結(jié)果如下:

可見,com1刪除之后,這個數(shù)值的空間釋放掉了,同時它的事件監(jiān)聽函數(shù)也不會再執(zhí)行了。

其它注意事項

$off的格式:

  • $off() 會取消所有的事件訂閱;
  • $off('事件名') 會取消指定事件名的;
  • $off('事件名', 回調(diào)) 會取消指定事件名的,指定回調(diào)

父子組件的created和mounted的區(qū)別, 按執(zhí)行順序:

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

所以,到底在哪個鉤子中訂閱,在哪個鉤子中發(fā)布,要根據(jù)情況來定。

小結(jié)

eventBus是一個名詞,并非前端獨有;

new Vue() 得到的實例上已經(jīng)實現(xiàn)了發(fā)布訂閱模式,可以直接做eventBus使用;

使用eventBus要及時調(diào)用$off;

總結(jié)

以上是生活随笔為你收集整理的vue 关闭弹如何销毁子组件_vue中的eventBus会产生内存泄漏吗的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。