vue組件通信&&v兄弟組件通信eventbus遇到的問題(多次觸發、第一次不觸發)


組件通訊包括:父子組件間的通信和兄弟組件間的通信。在組件化系統構建中,組件間通信必不可少的 (vuex以后再說)。

父組件--> 子組件

1. 屬性設置

父組件關鍵代碼如下:

1 <template>
2     <Child :child-msg="msg"></Child>
3 </template>

子組件關鍵代碼如下:

1 export default {
2   name: 'child',
3  props: {
4     child-msg: String
5   }
6 };

child-msg 為父組件給子組件設置的額外屬性值,屬性值需在子組件中設置props,子組件中可直接使用child-msg變量。

2. 子組件調用父組件

子組件通過 $parent 獲得父組件,通過 $root 獲得最上層的組件。

子組件--> 父組件

1. 發送事件/監聽事件

子組件中某函數內發送事件:

this.$emit('toparentevent', 'data');

父組件監聽事件:

<Child @toparentevent="toparentevent"></Child>
// 在methods里接收
methods: {
 toparentevent(msg) {
     // msg就是傳遞的數據
     console.log(msg) 
   }
}        

toparentevent 為子組件自定義發送事件名稱,父組件中@toparentevent為監聽事件,toparentevent為父組件處理方法。

2. 父組件直接獲取子組件屬性或方法

給要調用的子組件起個名字。將名字設置為子組件 ref 屬性的值。

<!-- 子組件。 ref的值是組件引用的名稱 -->
<child-component ref="aName"></child-component>

父組件中通過 $refs.組件名 來獲得子組件,也就可以調用子組件的屬性和方法了。

// 獲取child.屬性
this.$refs.aName.child
// 調用child.方法()
this.$refs.aName.child()

父組件通過 $children 可以獲得所有直接子組件(父組件的子組件的子組件不是直接子組件)。需要注意 $children 並不保證順序,也不是響應式的。

eventBus中央通信

各組件可自己定義好組件內接收外部組件的消息事件即可,不用理會是哪個組件發過來;而對於發送事件的組件,亦不用理會這個事件到底怎么發送給我需要發送的組件。

先設 main.js 置Bus

// main.js中
new Vue({
    el: '#app',
    router,
    template: '<App/>',
    components: { App },
    data: {
      eventBus: new Vue()
    }
  })

組件內監聽事件:

1 created() {
2     this.$root.eventBus.$on('childa-message', function(data) {
3       console.log(data);
4     });
5   }

發送事件的組件:

this.$root.eventBus.$emit('childa-message', this.data)
可能存在如下問題:
1.第一次觸發的時候頁面中的on事件沒有被觸發
2. 為什么后面再一次依次去觸發的時候會出現,每一次都會發現好像之前的on事件分發都沒有被撤銷一樣,導致每一次的事件觸發執行越來越多  

解答:

1. 當我們還在頁面A的時候,頁面B還沒生成,也就是頁面B中的 created中所監聽的來自於A中的事件還沒有被觸發。這個時候當你A中emit事件的時候,B其實是沒有監聽到的,

    當你從頁面A到頁面B跳轉的時候,發生了什么?首先是先B組件先created然后beforeMount接着A組件才被銷毀,A組件才執行beforeDestory,以及destoryed

    所以,我們可以把A頁面組件中的emit事件寫在beforeDestory中去。因為這個時候,B頁面組件已經被created了,也就是我們寫的$on事件已經觸發了

    修改如下:在beforeDestory生命周期里,$emit事件

1 beforeDestroy () {
2  this.$root.eventBus.$emit('child-message',this.data)
3  }

 2.  因為B頁面$on事件是不會自動清楚銷毀的,需要我們手動來銷毀,所以我在B組件頁面中添加Bus.$off來關閉,銷毀后就不存在執行多次的情況了   。代碼如下: 

1 // 在B組件頁面中添加以下語句,在組件beforeDestory的時候銷毀。
2  beforeDestroy () {
3     this.root.eventBus.$off('child-message')
4 },

               

總結: 所以,要用eventBus 來進行頁面組件之間的數據傳遞,需要注意亮點,組件A$emit事件應在beforeDestory生命周期內。其次,組件B內的$on記得要銷毀。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM