1. 程式人生 > >Vue提高篇-元件間的通訊

Vue提高篇-元件間的通訊

1.通訊示意圖

2.props(父級向子級傳遞)

<div id="app">
    <my-component icon-text="父傳到子的資料"></my-component>
</div>

Vue.component('my-component',{
    props:[iconText],
    template:'<span>{{ iconText }}</span>'
})
var app=new Vue({
    el:"#app"
})

輸出結果:<span>父傳到子的資料</span>

注意點:

       1.props的陣列中可盛放很多的傳遞引數;

       2.子元件的屬性皆為小寫(html的規定),但props裡需改為駝峰命名書寫;

       3.props的傳遞是單向的,只允許父級傳遞給子級,反過來不允許(vue1.*還是可以通過 ‘.sync’ 修飾符實現雙向資料流的);

       4.props中屬性使用靜態資料傳遞的值皆為字串,不可傳遞數字,布林,陣列,物件;

       5.props中屬性使用動態資料傳遞可將所有資料型別進行傳遞,彌補上一條的不足;

       6.以上程式碼使用的是陣列盛放props傳遞值,不僅如此,可使用物件進行傳遞,來實現傳遞值的資料型別,初始值等資料驗證;

Vue.component('my-exl',{
    props:{
        iconText:{
            type:Number,    //資料型別  或者限定:[Number,String]
            default:123,        //資料預設值
            required:true,          //資料是否必傳
            validatoe:function(val){    //驗證失敗成功回撥函式
                return val>10
            }
        },
        ......
    }
}) 

 

3.$emit(子級自定義事件傳遞值給父級)

//子元件
<template>
    <div>
        <button @click='clickFn(`石家莊`)'>點選此處將‘石家莊’發射給父元件</button>
        <span> 父元件傳過的值為:{{sendData}} </span>
    </div>
</template>

<script>
    export default {
        name:'city',
        props:['sendData'], // 父元件傳給子元件的值
        methods:{
            clickFn (val) {    //子元件按鈕點選觸發事件函式
                let data = {    //子元件向上傳遞的值定義
                    city: val,
                    show:true
                };
                this.$emit('upvalue',data);    //clickFn事件觸發後,自動觸發upvalue事件
            }
        }
    }
</script>


//父元件
<template>
    <div>
        <city @upvalue="updateCity" :sendData="toCity"></city>
        <span v-show="show"> 子元件按鈕點選傳過的值為:{{toCity}} </span>
    </div>
<template>
<script>
    import City from "./city";    //父元件匯入子元件
    export default {
        name:'index',
        components: {City},    //父元件使用子元件
        data () {
            return {
                toCity:"北京",
                show:false
            }
        },
        methods:{
            updateCity(data){    //觸發子元件的更新城市事件(自動觸發的)
            this.toCity = data.city;    //改變了父元件的值
            this.show = data.show;
        }
    }
}
</script>

注意點:

       1.使用 $emit 為自定義的事件,如未規定觸發函式,則此事件即為無效;

       2.使用 $emit 中事件名稱必須一一對應,不可出現複用,關鍵字使用的情況,不然可能會出現意想不到的錯誤;

       3.自定義事件基本流程:

                 vm.$emit( event(事件名稱), arg(傳遞資料,可為陣列,物件) )         //點選觸發-觸發子元件上的事件

                 v-event(自定義事件名稱)=“eventFn”             //自動觸發-監聽event事件後執行 eventFn

       4.一般在父元件的eventFn中,我們會將傳過來的值進行賦值,方便當前例項使用;

4.事件匯流排(兄弟元件間傳值)

//兄弟1元件
Vue.component('b1',{
    data(){
        return {
            b1Val:'b1元件的內容'
        }
    },
    template:'<div><input type="text" v-model="b1Val" @input="passData(b1Val)"></div>',
    methods:{
        passData(val){
            bus.$emit('globalEvent',val)    //觸發全域性事件globalEvent
        }
    }
})
//兄弟2元件
Vue.component('b2',{
    data(){
        return {
            b2Val:'hello b2Val',
            formb1:''
        }
    },
    template:"<div><p>b1傳遞過來的資料:{{formb1}}</p></div>",
    mounted(){
        bus.$on('globalEvent',(val)=>{     //繫結全域性事件globalEvent
            this.formb1=val;
        })
    }
})
//中央事件匯流排
var bus=new Vue();

var app=new Vue({
    el:'#app'
})

注意點:

       1.事件匯流排的基本是:定義一個全域性的vue例項,使他成為一個橋樑來定義事件並觸發事件;

       2.需要傳值的元件中用bus.$emit觸發一個自定義事件,並傳遞引數;

       3.需要接收資料的元件中用bus.$on監聽自定義事件,並在回撥函式中處理傳遞過來的引數;

5.vuex處理元件間的資料互動

當(1)業務邏輯複雜(2)存在過多的通訊傳值(3)可能存在共同處理的資料,以上方法就不夠看了,因此新的概念出來了,那就是vuex。vuex的做法就是將這一些公共的資料抽離出來,然後其他元件就可以對這個公共資料進行讀寫操作,這樣達到了解耦的目的。下一章我會專門對此進行總結。