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

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

父組件--> 子組件

1. 屬性設置

父組件關鍵代碼以下:vuex

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

子組件關鍵代碼以下:app

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

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

2. 子組件調用父組件

子組件經過 $parent 得到父組件,經過 $root 得到最上層的組件。組件化

子組件--> 父組件

1. 發送事件/監聽事件

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

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

父組件監聽事件:spa

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

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

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

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

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

父組件中經過 $refs.組件名 來得到子組件,也就能夠調用子組件的屬性和方法了。router

// 獲取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記得要銷燬。

相關文章
相關標籤/搜索