1. 程式人生 > >【前端框架-Vue-基礎】$attr及$listeners實現跨多級組件的通信

【前端框架-Vue-基礎】$attr及$listeners實現跨多級組件的通信

開發 發現 ttr 原因 temp com turn 三種 als

父子

A 組件與 B 組件之間的通信: (父子組件)
如上圖所示,A、B、C三個組件依次嵌套,按照 Vue 的開發習慣,父子組件通信可以通過以下方式實現:

A to B 通過props的方式向子組件傳遞,B to A 通過在 B 組件中 $emit, A 組件中 v-on 的方式實現
通過設置全局Vuex共享狀態,通過 computed 計算屬性和 commit mutation的方式實現數據的獲取和更新,以達到父子組件通信的目的。
Vue Event Bus,使用Vue的實例,實現事件的監聽和發布,實現組件之間的傳遞。
往往數據在不需要全局的情況而僅僅是父子組件通信時,使用第一種方式即可滿足。

跨多級

A 組件與 C 組件之間的通信: (跨多級的組件嵌套關系)
如上圖,A 組件與 C 組件之間屬於跨多級的組件嵌套關系,以往兩者之間如需實現通信,往往通過以下方式實現:

借助 B 組件的中轉,從上到下props依次傳遞,從下至上,$emit事件的傳遞,達到跨級組件通信的效果
借助Vuex的全局狀態共享
Vue Event Bus,使用Vue的實例,實現事件的監聽和發布,實現組件之間的傳遞。

問題

顯然,第一種通過props和$emit的方式,使得組件之間的業務邏輯臃腫不堪,B組件在其中僅僅充當的是一個中轉站的作用。如使用第二種 Vuex的方式,某些情況下似乎又有點大材小用的意味,(僅僅是想實現組件之間的一個數據傳遞,並非數據共享的概念)。第三種情況的使用在實際的項目操作中發現,如不能實現很好的事件監聽與發布的管理,往往容易導致數據流的混亂,在多人協作的項目中,不利於項目的維護。

解決方案

在ABC父子孫三個組件中,子組件及B中代碼類似下面這樣:

<template>
 <div class="child-1">
 <p>in child1:</p>
 <p>props: {{pChild1}}</p>
 <p>$attrs: {{$attrs}}</p>
 <hr>
 <!-- C組件中能直接觸發test的原因在於 B組件調用C組件時 使用 v-on 綁定了$listeners 屬性 -->
 <!-- 通過v-bind 綁定$attrs屬性,C組件可以直接獲取到A組件中傳遞下來的props(除了B組件中props聲明的) -->
 <child2 v-bind="$attrs" v-on="$listeners"></child2>
 </div>
</template>
<script>
 import Child2 from ‘./Child2.vue‘;
 export default {
 props: [‘pChild1‘],
 data () {
 return {};
 },
 inheritAttrs: false,
 components: { Child2 },
 mounted () {
 this.$emit(‘test1‘);
 }
 };
</script>

v-bind屬性$attr,保證C組件能夠獲取到A組件傳遞下來的props(除props屬性中聲明的屬性以外);

而v-bind屬性$listeners,則保證C組件能直接調用A組件的方法。

【前端框架-Vue-基礎】$attr及$listeners實現跨多級組件的通信