vue——爺孫組件之間通信


參考: vue父、子、孫組件間數據傳遞、事件傳遞 - 掘金 (juejin.cn)

 

方式一. 利用$attrs實現祖孫組件間的數據傳遞,$listeners實現祖孫組件間的事件監聽

$attrs包含了父作用域中不作為 prop 被識別 (且獲取) 的特性綁定 (class 和 style 除外)。當一個組件沒有聲明任何 prop 時,這里會包含所有父作用域的綁定 (class 和 style 除外),並且可以通過 v-bind="$attrs" 傳入內部組件——在創建高級別的組件時非常有用。
$listeners包含了父作用域中的 (不含 .native 修飾器的) v-on 事件監聽器。它可以通過 v-on="$listeners" 傳入內部組件——在創建更高層次的組件時非常有用。
例:
 
爺組件:
<div>
     <my-mask :show="isShow" :title="title" :con="con" @on-submit="submit"></my-mask>
</div>
... ... components: { myMask, // 子組件 }, data() { return { isShow: false, title: '我是標題', con: '我是內容', }; }, methods: { submit() { window.alert('關閉彈層'); this.isShow = false; }, } ... ...

子組件my-mask:

<div class="mask" v-if="show">
    <div class="mask-bg"></div>
    <alert v-bind="$attrs" v-on="$listeners"></alert>
</div>

... ...

    components: {
        alert, // 孫組件
    },
    inheritAttrs: false,
    data() {
        return {}
    },
    props: ['show'],
... ...

爺組件在傳遞數據給子組件的時候,如果子組件沒有通過props接收祖組件傳遞的參數,那么這個數據會表現在子組件的根標簽的屬性上;通過設置 inheritAttrs 為 false,這些默認行為將會被去掉。

然后我們可以在子組件綁定v-bind="$attrs",將這些特性傳遞給孫組件,孫組件通過props接收數據,同理可以通過 $listeners 實現爺孫之間的事件監聽器傳遞。

 

孫組件alert:

<div class="alert">
    <h2>{{title}}</h2>
    <div class="alert-con">{{con}}</div>
    <button class="submit" @click="submit">確定</button>
</div>

... ...

  data() {
        return {}
    },
    props: ['title', 'con'], // title和con來自於爺組件
    methods: {
        submit() {
            this.$emit('on-submit'); // 會觸發爺組件的submit事件
        }
    }
... ...

 

 

方式二. 利用provide/inject 實現祖孫組件間的數據傳遞和事件監聽

provide 和 inject 主要為高階插件/組件庫提供用例,允許一個祖先組件向其所有子孫后代注入一個依賴,不論組件層次有多深,並在起上下游關系成立的時間里始終生效。

 

例:

 

爺組件:

<div>
    <my-con></my-con>
</div>

... ...

 components: {
        myCon, // 子組件
    },
    provide() {
        return {
            store: this.store
        }
    },
    data() {
        return {
            store: {
                state: {
                    type: 0
                },
                commit (type, value) {
                    this.state[type] = value
                }
            },
        };
    },
    methods: {
        changeCon() {
            this.store.state.type ++;
            if(this.store.state.type > 2) this.store.state.type = 0;
        },
    },
... ...

 

子組件my-con:

<div>
    <my-table></my-table>
</div>

... ...

    components: {
        myTable, // 孫組件
    },
    props: [],
... ...

孫組件my-table:

<div>
    <div class="tab-list">
        <span class="tab-item" v-for="(item, index) in list" @click="switchType(item.type)" :class="{'active': item.type === store.state.type}">{{item.value}}</span>
    </div>
</div> 

... ...

     data() {
        return {
            tableType: 0,
            list: [{value: '新聞', type: 0}, {value: '汽車', type: 1},{value: '娛樂', type: 2}]
        }
    },
    inject: ['store'],
    methods: {
        switchType(value) {
            this.store.commit('type', value)
        }
    }
... ...

 


免責聲明!

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



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