91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

vue中的eventBus會產生內存泄漏嗎

發布時間:2022-02-14 09:52:57 來源:億速云 閱讀:155 作者:小新 欄目:開發技術

這篇文章主要介紹了vue中的eventBus會產生內存泄漏嗎,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

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

引入

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

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

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

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

EventBus可以代替Android傳統的Intent,Handler,Broadcast或接口函數,在Fragment,Activity,Service線程之間傳遞數據,執行方法。

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

內容

  • 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。

它可以幫助我們實現跨組件的通信。

vue中的eventBus會產生內存泄漏嗎

例子:使用eventBus

在根組件中發布事件,在兩個子組件中去監聽事件。

vue中的eventBus會產生內存泄漏嗎

<div id="app">
   <h3>eventBus的基本使用</h3>
   <com1></com1>
   <com2></com2>
 </div>
 <script>
   Vue.prototype.$eventBus = new Vue()
   Vue.component('com1', {
     template:`<div>com1</div>`,
     created () {
       this.$eventBus.$on('event1', function f1(d){
         conse.log(d, 'com1 listen...  event1')
       })
     },
   })
   Vue.component('com2', {
     template:`<div>com2</div>`,
     created () {
       this.$eventBus.$on('event2', function f2(d) {
         conse.log(d, 'com2 listen...  event2')
       })
     }
   })
   var vm = new Vue({
     el: '#app',
     created () {
       setInterval( () => {
         const d = Date.now()
         this.$eventBus.$emit('event1', d)
         this.$eventBus.$emit('event2', d)
       }, 3000)
     }
   })
 </script>

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

效果如下:

vue中的eventBus會產生內存泄漏嗎

例子:不及時取消訂閱

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

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

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

<div id="app">
   <h3>不及時取消訂閱的問題</h3>
   <button @click="showCom1=!showCom1">
     {{showCom1 ? "銷毀" : "重建"}}組件1
   </button>
   <com1 v-if="showCom1"></com1>
   <com2></com2>
 </div>
 <script>
   Vue.prototype.$eventBus = new Vue()
   Vue.component('com1', {
     template:`<div>com1</div>`,
     created () {
       conse.log('創建com1')
       this.$eventBus.$on('event1', function f1(d) {
         conse.log(d, 'com1 listen... event1')
       })
     }
   })
   Vue.component('com2', {
     template:`<div>com2</div>`,
     created () {
       this.$eventBus.$on('event2', function f2(d) {
         conse.log(d, 'com2 listen... event2')
       })
     }
   })
   var vm = new Vue({
     el: '#app',
     data:{
       showCom1: true
     },
     created () {
       setInterval( () => {
         const d = Date.now()
         this.$eventBus.$emit('event1', d)
         this.$eventBus.$emit('event2', d)
       }, 3000)
     }
   })
 </script>

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

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

上面的代碼執行的效果,是這樣的:

  • 銷毀組件1之后,它還能正常收到event1事件,并執行回調;

  • 再次創建組件1后,它會再次訂閱event1事件,所以結果是執行兩次回調。

vue中的eventBus會產生內存泄漏嗎

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

 Vue.component('com1', {
   template:`<div>com1</div>`,
   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添加一個快照,查看結果如下:

vue中的eventBus會產生內存泄漏嗎

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

解釋如下:

vue中的eventBus會產生內存泄漏嗎

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

解決方案:

在com1的destoryed鉤子中,調用$off來取消訂閱。

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

調試結果如下:

可見,com1刪除之后,這個數值的空間釋放掉了,同時它的事件監聽函數也不會再執行了。

其它注意事項

$off的格式:

  • $off() 會取消所有的事件訂閱;

  • $off('事件名') 會取消指定事件名的;

  • $off('事件名', 回調) 會取消指定事件名的,指定回調

父子組件的created和mounted的區別, 按執行順序:

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

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

所以,到底在哪個鉤子中訂閱,在哪個鉤子中發布,要根據情況來定。

感謝你能夠認真閱讀完這篇文章,希望小編分享的“vue中的eventBus會產生內存泄漏嗎”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

寿光市| 长武县| 仙游县| 镇安县| 延安市| 多伦县| 城市| 邮箱| 靖州| 石阡县| 龙川县| 东辽县| 临夏市| 宾阳县| 吉林市| 鹤庆县| 启东市| 九龙城区| 新蔡县| 宽甸| 临湘市| 扬中市| 鲁甸县| 商洛市| 垫江县| 宣威市| 白银市| 河东区| 英吉沙县| 长子县| 元朗区| 小金县| 墨脱县| 阳新县| 富锦市| 东乡县| 阜阳市| 政和县| 昆山市| 上虞市| 安新县|