溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

vue中組件間相互通信傳值的方法有哪些

發(fā)布時間:2022-02-28 14:42:54 來源:億速云 閱讀:141 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要講解了“vue中組件間相互通信傳值的方法有哪些”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“vue中組件間相互通信傳值的方法有哪些”吧!

    vue中組件之間相互通訊傳值的方式

    我們在使用vue進行項目開發(fā)的時候為了更好地管理項目,我們會把每個功能封裝成一個個的組件,在使用的時候直接引入并且調(diào)用組件來實現(xiàn)代碼的復(fù)用。

    我們在封裝組件的時候經(jīng)常會留有一些預(yù)留的接口,供使用的時候調(diào)用和傳入不同的數(shù)據(jù),這個時候我們就涉及到了組件之前的相互傳值的問題。

    我這里總結(jié)了在vue中組件之前相互傳值的方法:

    1、子組件和父組件通訊,通過調(diào)用父組件給組件自定義屬性值來實現(xiàn)

    <!--parent.vue-->
    <template>
        <div>
            <h5>我是父組件:</h5>
            <p>這是我自己的數(shù)據(jù){{num}}</p>
            <!--通過給子組件傳入自定義屬性值,傳數(shù)據(jù)用v-bind或者簡寫形式:號, 傳方法可以使用v-on或者簡寫@符綁定事件-->
            <child :p-num="num" :p-num2="num2" @changePNum="changeNum" />
        </div>
    </template>
    <script>
        import child from './child.vue'
        export default{
            name: 'parent',
            data(){
                return{
                    num: 10,
                    num2: 20
                }
            },
            methods:{
                changeNum(n){
                    this.num = n;
                }
            }
        }
    </script>
    <!--child.vue-->
    <template>
        <div>
            <h5>我是子組件:</h5>
            <!--第一種可以使用props對象來接收父級傳過來的屬性-->
            <p>這是通過props接收父級組件傳過來的數(shù)據(jù){{ pNum}}</p>
            <!--第二種是通過元素的實例屬性$attrs獲取,沒有唄props接收的剩余屬性-->
            <p>這是通過組件中的$attrs對象獲取父級組件傳過來的數(shù)據(jù){{ $attrs['p-num2']}}</p>
            <!--第三種是通過當(dāng)前實例中的$parent屬性拿到父級實例對象-->
            <p>這是通過組件中的$attrs對象獲取父級組件傳過來的數(shù)據(jù){{ topNum }}</p>
            <button @click="changeNum">通過$emit改變父級的數(shù)據(jù)</button>
            <button @click="changeNum2">通過$listeners改變父級的數(shù)據(jù)</button>
            <button @click="changeNum3">通過$parent改變父級的數(shù)據(jù)</button>
        </div>
    </template>
    <script>
        export default{
            name: 'child',
            // 第一種可以使用props對象來接收父級傳過來的屬性
            props:{
                // 這里寫對應(yīng)的要接收的屬性名以駝峰的形式接收
                pNum: {
                    type: Number
                }  
            },
            data(){
                return {
                    topNum: 0
                }
            },
            created(){
                // 通過使用實例中的$parent拿到父級組件的實例,然后獲取值
                this.topNum = this.$parent.num;  
            },
            methods:{
                changeNum(){
                    // 這里是通過當(dāng)前組件中的$emit方法來調(diào)用父級傳過來的方法,并且可以傳入?yún)?shù)
                    this.$emit('changePNum', 40);
                },
                changeNum2(){
                    // 通過組件中的$listeners中的存儲的父級傳過來的方法進行調(diào)用
                    this.$listeners.changePNum(50);
                },
                changeNum3(){
                    // 通過組件中的$listeners中的存儲的父級傳過來的方法進行調(diào)用
                    this.$parent.changeNum(60);
                }
            }
        }
    </script>

    上邊的代碼展示了兩種不同形式的組件之間的通訊方式,父組件傳值方式相同,子組件獲取操作方式不同

    1.props/$emit組合方式:子組件通過定義props值拿到父組件傳給子組件的屬性來獲取;子組件通過使用$emit方法調(diào)用父組件的方法;

    2.$attrs/$listeners組合方式:子組件可以通過$attrs屬性中的值拿到父組件傳給子組件的屬性值,它里邊存儲的是props之外的屬性值;

    3.$parent方法獲取父組件中的數(shù)據(jù)和方法

    2、父組件主動獲取子組件數(shù)據(jù)

    <!--parent-->
    <template>
        <div>
            <button @click="changeChildANum">通過$refs調(diào)用子組件方法更改子組件數(shù)據(jù)</button>
            <button @click="changeChildBNum">通過$children調(diào)用子組件方法更改子組件數(shù)據(jù)</button>
            <p>這是獲取的子組件childA的數(shù)據(jù):{{childA_num}}</p>
            <p>這是獲取的子組件childB的數(shù)據(jù):{{childB_num}}</p>
            <!--這里通過使用ref把組件示例注冊到當(dāng)前組件的$refs中-->
            <child-a ref="childA"/>
            <child-b />
        </div>
    </template>
    <script>
        import childA from './childA.vue';
        import childB from './childA.vue';
        export default{
            components:{
                childA,
                childB
            },
            data(){
                return {
                    childA_num: 0,
                    childB_num: 0
                }
            },
            created(){},
            mounted(){
                // $refs 和 $children 都是需要在mounted中才能獲取到
                // 這里通過$refs獲取注冊在里邊的子組件實例,并且獲取他的數(shù)據(jù)
                this.childA_num = this.$refs.childA.num
                // 第二種方式通過當(dāng)前組件示例中的$children獲取子組件實例
                this.childB_num = this.$children[1].num;
            },
            methods:{
                changeChildANum(){
                    // 這里通過使用$refs中的組件實例調(diào)用組件中的方法
                    this.$refs.childA.changeNum();
                },
                changeChildBNum(){
                    // 這里通過使用$refs中的組件實例調(diào)用組件中的方法
                    this.$children[1].changeNum();
                }
            }
        }
    </script>
    <!--child-->
    <template>
        <div></div>
    </template>
    <script>
        export default{
            name: 'childA',
            data(){
                return{
                    num: 10
                }
            },
            methods:{
                changeNum(){
                    this.num++;
                }
            }
        }
    </script>

    1.ref/$refs方式,通過給引入的組件定義一個ref屬性,然后就可以通過$refs結(jié)合該屬性值得到當(dāng)前組件的實例

    2.ref/$children屬性,給組件定義ref值后,當(dāng)前組件實例中會在this.$children中拿到所有定義了ref的組件數(shù)組,我們在通過下標進行獲取某個子組件的方法后者屬性值。

    3、使用provide/inject方法實現(xiàn)

    <!--parent.vue-->
    <template>
        <div>
            <child />
        </div>
    </template>
    <script>
        import child from './child.vue';
        export default{
            // 通過給父級定義一個provide對象,并且定義成一個函數(shù)形式,然后返回一個parentData對象,并且對象指向當(dāng)前組件的一個數(shù)據(jù)對象上,這樣相當(dāng)于都指向一個對象
            provide(){
                return {
                    parentData: this.proVideData
                }
            }
            name: 'Parent',
            components:{
                child
            },
            data(){
                return{
                    proVideData: {
                        num, 1,
                        changeNum: null
                    }
                }
            },
            created(){
                // 然后通過實例化后把需要被子組件調(diào)用到的方法傳入進去
                this.proVideData.changeNum = this.changeNum;
            },
            methods:{
                changeNum(){
                    this.proVideData.num++;
                }
            }
        }
    </script>
    <!--child.vue-->
    <template>
        <div>
            <p>{{parentData.num}}</p>
            <button @click="parFun">調(diào)用父級的方法</button>
        </div>
    </template>
    <script>
        export default{
            // 子組件通過inject接到祖先組件中的provide廣播的數(shù)據(jù)
            inject:['parentData'],
            name: 'child',
            data(){
                return{
                }
            },
            methods:{
               parFun(){
                    // 這里直接執(zhí)行存儲下來的方法
                   this.parentData.changeNun();
               } 
            }
        }
    </script>

    這種方式適合層級比較深的組件傳值,這里的基本原理是,通過給祖先組件配置provide屬性,然后把想要傳給后代組件的屬性值,進行存儲;
    然后在后代組件中,那個需要拿到傳播的數(shù)據(jù),可以給組件本身配置injuct屬性,來接收想要監(jiān)聽的數(shù)據(jù)值;

    然后就可以進行通信了

    4、使用事件總線

    此方發(fā)可以在任意組件中進行監(jiān)聽當(dāng)前定義的方法。來實現(xiàn),組件間相互通信

    <!--event-bus.js-->
    import Vue from 'vue';
    // 這里從創(chuàng)建了一個新的vue實例對象
    export const EventBus = new Vue();
    <!--parent.vue-->
    <template>
        <div>
        </div>
    </template>
    <script>
    // 這里引入事件總線
    import { EventBus } from './event-bus';
    export default{
        data(){
            return{
                eventBusMsg: ''
            }
        },
        created(){
            // 然后給事件總線綁定一個需要監(jiān)聽的方法,類似于發(fā)布訂閱者的增加訂閱
            EventBus.$on("eventBusMsg", (msg) => {
                console.log(msg);
                this.eventBusMsg = msg;
            });
        },
        beforeDestroy(){
             EventBus.$small("eventBusMsg");
        }
    }
    </script>
    <!--sub.vue后代組件-->
    <template>
        <div>
            <button @click="eventBusChange">通過事件總線調(diào)用組件的方法</button>
        </div>
    </template>
    <script>
    // 其他組件也需要你引入該插件
    import { EventBus } from './event-bus';
    export default{
        data(){
        },
        created(){
        },
        methods:{
            eventBusChange(){
                //這里是通過eventBus來調(diào)用一個訂閱的消息方法,并傳入值過去
                EventBus.$emit('eventBusMsg', 'childB');
            }
        }
    }
    </script>

    事件總線的調(diào)用方式是:

    1.定義一個全局的vue示例并導(dǎo)出;

    2.然后在需要監(jiān)聽某個事件的組件中引入event-bus

    3.給當(dāng)前的組件在created方法中增加方法

    4.然后子組件可以通過引入event-bus文件然后通過EventBus.$emit方式執(zhí)行監(jiān)聽的時間方法

    5、vuex\localStorage\sessionStorage

    還可以使用Vuex、本地存儲等方式來實現(xiàn)全局公用。

    感謝各位的閱讀,以上就是“vue中組件間相互通信傳值的方法有哪些”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對vue中組件間相互通信傳值的方法有哪些這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

    向AI問一下細節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

    vue
    AI