在Vue中,實現組件間通訊的方式有很多種。其中,使用 $emit 和 $on 方法可以實現子組件向父組件傳遞數據。這兩個方法使用的是父子組件間的通訊,需要在父組件中指定事件名稱并在子組件中觸發。
但有時我們需要實現跨級組件通訊,或者在子組件中觸發一個事件并讓其他子組件同時響應,這時候 $emit 和 $on 就不再適用了。這時候,Vue提供了一種特殊的變量:this.$listeners。
this.$listeners 實際上是父組件傳遞給子組件的一個對象類型的屬性,包含了所有在父組件中綁定在當前組件的所有事件。子組件可以通過回調函數或者其他方式觸發一些事件并讓父組件得知,并讓其他子組件同時響應。這樣就實現了跨級組件間的通訊。
computed: {
eventName () {
return `event-${this.yourEvent}`
}
},
methods: {
emitEvent () {
this.$emit(this.eventName, this.yourEventData)
}
}
在子組件中,可以通過 this.$listeners 對象來獲取父組件傳遞過來的所有事件。this.$listeners 是一個對象類型的屬性,包含了父組件中綁定給自身的所有事件監聽器。也就是說,我們可以在子組件中遍歷 this.$listeners 對象中的所有成員,并進行一些操作。
<template>
<div>
<span>Event Name:</span>
<span>{{ eventName }}</span>
<button @click="emitEvent">Emit Event</button>
<div v-for="(listener, key) in $listeners" :key="key">
<div>{{ key }}:</div>
<div>{{ listener }}
上面的代碼演示了一個子組件如何使用 this.$listeners 對象遍歷父組件傳遞過來的所有事件,并實現了子組件在點擊按鈕后觸發事件并向父組件傳遞數據。在模板中我們綁定了一個事件監聽器,并使用 v-for 遍歷 this.$listeners 中的所有事件。可以看到,this.$listeners 包含了所有父組件綁定給自身的事件監聽器,包括事件名和回調函數。
需要注意的是,this.$listeners 會同時包含一些額外的屬性,這些屬性使用的是 $ 符號開頭的屬性名稱。這些屬性由 Vue 自身使用,我們在遍歷 this.$listeners 時需要避開這些屬性。
總之,this.$listeners 提供了一種跨級組件通訊的方式,并且在一些場景中可以避免使用一些復雜的設計模式。如果你的組件需要在多個層級間進行通訊,就可以考慮使用 this.$listeners。