vue組件傳值(8種方法)----props、$emit()、手動封裝事件訂閱observer、事件總線(Eventbus)、vuex、親兄弟傳值、provide/inject、插槽作用域


 

    1、父傳子

        傳遞:當子組件中在父組件中當做標簽使用的時候,給子組件綁定一個自定義屬性,值為需要傳遞的數據
        接收:在子組件內部通過props進行接收,props接收的方式有2種:
            ①通過數組進行接收   props:["屬性"]
            ②通過對象進行接收    props:{
                                    屬性:{
                                        (1)type:限制數據的類型
                                        (2)default:默認值
                                        (3)required:布爾值,和default二選一
                                    }
                                }
        步驟:
            ①在父組件中給子組件標簽上添加自定義屬性:
                <son :custom="100"></son>
            ②子組件中通過props接收:
                props:["custom"]
            ③接收到的custom可以直接在標簽中使用 {{custom}}
        注意:今后只要看到props就要想到這個屬性是用來接收外部數據的。

 

    2、子傳父

        ①接收:當子組件在父組件中當做標簽使用的時候,給當前子組件綁定一個自定義事件,值為需要接收值的函數,這個函數不允許加 ()
        ②傳遞的過程:在子組件內部通過this.$emit("自定義事件名稱",需要傳遞的參數)來進行數據的傳遞
        步驟:
            ①父組件中給需要接收參數的子組件綁定自定義事件,值為需要接收值的函數:
                <son @handler="handlerMsg"></son>

 

                methods:{
                    handlerMsg(value){
                        console.log(value)// 這個值是通過this.$emit()觸發傳來的
                    }
                }
            ②子組件中觸發自定義事件:
                this.$emit("handler",100);

 

    3、非父子傳遞

        第一種方法:通過給vue原型上添加一個公共的vue實例對象(vue實例對象上有$on()和$emit()),需要傳遞的一方調用$emit(),需要接收的一方調用$on()。

        步驟:
            ①main.js中:
                Vue.prototype.$observer=new Vue();
            ②需要傳遞的組件中:
                this.$observer.$emit("handler",100);
            ③需要接收的組件中:
                this.$observer.$on("handler",(value)=>{
                    console.log(value)
                });
                注意:在掛載前(created)進行$on()綁定,先綁定好,再觸發。

 

        *第二種方法:手動封裝事件訂閱observer

            步驟:
                ①src下新建observer.js:
                    const eventList={};

                    const $on=function (eventName,callback) {  
                        if(!eventList[eventName]){
                            eventList[eventName]=[];
                        }
                        eventList[eventName].push(callback);
                    }

                    const $emit=function(eventName,params){
                        if(eventList[eventName]){
                            let arr=eventList[eventName];
                            arr.forEach((cb)=>{
                                cb(params);
                            });
                        }
                    }

                    const $off=function(eventName,callback){
                        if(eventList[eventName]){
                            if(callback){
                                let index=eventList[eventName].indexOf(callback);
                                eventList[eventName].splice(index,1);
                            }else{
                                eventList[eventName].length=0;
                            }
                        }
                    }

                    export default{
                        $on,
                        $emit,
                        $off
                    }
                ②main.js中用手動封裝的observer替代new Vue()
                    import observer from "./observer.js";
                    Vue.prototype.$observer=observer;
                ③在需要傳遞的組件中用this.$observer.$emit()觸發自定義事件:
                    this.$observer.$emit("customHandler","需要傳遞的值");
                ④在需要接收的組件中用this.$observer.$on()綁定自定義事件:
                    this.$observer.$on("customHandler",this.toggle);





        第三種方法:事件總線(Eventbus)

            步驟:
                ①先創建一個空實例:
                    let bus=new Vue();
                ②通過bus.$on()綁定自定義事件:
                    bus.$on("customHandler",要觸發的函數);
                ③通過bus.$emit()來觸發自定義事件: 
                    bus.$emit("customHandler");

 

        *第四種方法:vuex(后續)



        注:如果是親兄弟:(父傳子和子傳父)

            步驟:
                ①父組件中聲明data數據 state:true ,將state通過props傳給其中一個子組件:
                    <two :show="state"></two>

 

                    props:show

 

                    此時show的值隨着state的變化而變化

 

                ②再通過另一個子組件去改變父組件的state:
                    標簽上綁定自定義事件:
                        <one @customHandler="toggle"></one>
                    再在子組件內部通過$emit()觸發customHandler事件:
                        this.$emit("customHandler");



provide / inject(提供/注入)跨組件傳值,其實就是父傳子


    provide / inject:依賴注入。可以實現跨組件傳值,數據的流向只能是向下傳遞,就是大范圍有效的props

    provide:這個配置項必須要在父級進行使用,用來定義后代組件所需要的一些屬性和方法。
        語法:
            provide:{

            }
            // 推薦
            provide(){
                return{

                }
            }

 

    inject:這個配置項必須在后代組件中使用,用來獲取根組件定義的跨組件傳值的數據。
        語法:
            inject:[] 

            // 推薦
            inject:{
                key:{
                    from:"父組件名稱",
                    default:默認值
                }
            }

 

插槽 slot

    作用:默認情況下組件內部包裹的內容是不會顯示的,如果需要進行顯示則需要通過插槽來進行顯示。

    1、匿名插槽:沒有名字的插槽(v-slot:default)

        v-slot
        在組件內部通過<slot></slot>進行接收

        步驟:
            ①App.vue中在組件標簽中添加template標簽(里面可以寫多個標簽),寫上v-slot屬性
                <Header>
                    <template v-slot>
                        <p>111</p>
                        <p>222</p>
                    </template>
                </Header>
            ②在Header.vue組件中通過<slot></slot>開辟一塊空間:
                <div class="header">
                    <slot></slot>
                </div>
    

    2、命名插槽:有名字的插槽

        v-slot:slotName
        在組件內部通過<slot name="slotName"></slot>來進行接收

        步驟:
            ①給插槽指令加上名字:
                <template v-slot:slotName>
                    <p>111</p>
                </template>
            ②slot標簽添加name屬性:
                <div class="header">
                    <slot name="slotName"></slot>
                </div>

            如果還有匿名插槽template,就在Header.vue中用<slot></slot>再開辟一塊空間接收匿名插槽。
    

    3、插槽作用域:(子傳父)

        v-slot:slotName(名字可寫可不寫,如果不寫默認是default)="變量(這個變量是一個對象)"

        作用:讓組件來提供自身需要顯示的內容

        步驟:
            ①App.vue中template中設置v-slot="props"(props是一個對象):---------父
                <template v-slot="props">
                    <h2>{{props.info}}</h2>
                </template>
            ②Header.vue中slot標簽綁定自定義屬性info:----------子,info屬性的值提供給父組件中的props.info
                <div class="header">
                    <slot :info="'111'"></slot>
                </div>
            ③在template中可以通過props.info拿到子組件中傳來的值
 
            如果要用命名插槽:
                App.vue:直接在v-slot后面加上 :slotName
                Header.vue:<slot name="slotName" :info="'111'"></slot>


















免責聲明!

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



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