天天看點

Vue基于$attrs及$listeners實作隔代通信

所謂隔代通信就是A 與C的通信

A -> B -> C      
Vue基于$attrs及$listeners實作隔代通信

代碼執行個體

A.

vue
<template>
  <div id="app">
    <!-- 此處監聽了事件,可以在C元件中直接觸發 -->
    <b-child
    nameToB="nameToB" 
    nameToC="nameToC" 
    @buttonClick="buttonClick" 
   >
    </b-child>
  </div>
</template>


<script>
import BChild from "./B.vue";

export default {
  data() {
    return {};
  },
  
  components: { BChild },

  methods: {
    buttonClick() {
      console.log("buttonClick...");
    }
  }
};
</script>
      

B.vue

<template>
    <div>
        <h1>B元件</h1>
        <p>name: {{nameToB}}</p>
        <p>$attrs: {{$attrs}}</p>
        <hr>
        <!-- C元件中能直接觸發buttonClick的原因在于 B元件調用C元件時 使用 v-on 綁定了$listeners 屬性 -->
        <!-- 通過v-bind 綁定$attrs屬性,C元件可以直接擷取到A元件中傳遞下來的props(除了B元件中props聲明的) -->
        <c-child v-bind="$attrs" v-on="$listeners"></c-child>

    </div>
</template>

<script>
 import CChild from './C.vue';

 export default {
    props: ['nameToB'],
    
    components: { CChild },

    data () {
        return {};
    },

    // inheritAttrs: false,
 };
</script>      

C.vue

<template>
    <div>
        <h1>C元件</h1>
        <p>name: {{nameToC}}</p>
        <p>$attrs: {{$attrs}}</p>
        <button @click="buttonClick">點選C按鈕</button>
    </div>
</template>

<script>
    export default {
    // inheritAttrs: false,

        props: ['nameToC'],

        data () {
            return {};
        },
        
        methods: {
            buttonClick(){
                this.$emit('buttonClick');
            }
        }
    };
</script>      

最終,通過B實作了A與C的通信

Vue基于$attrs及$listeners實作隔代通信

參考

Vue v2.4中新增的a t t r s 及 attrs及attrs及listeners屬性使用教程

繼續閱讀