vue的$emit 與$on父子組件與兄弟組件的之間通訊

本文主要對vue 用$emit 與 $on 來進行組件之間的數據傳輸.vue

主要的傳輸方式有三種:vuex

1.父組件到子組件通訊

2.子組件到父組件的通訊api

3.兄弟組件之間的通訊數組

 

1、父組件傳值給子組件函數

父組件給子組件傳子,使用props學習

//父組件:parent.vue
<template>
    <div>
        <child :vals = "msg"></child>
    </div>
</template>
<script>
import child from "./child";
export default {
    data(){
        return {
            msg:"我是父組件的數據,將傳給子組件"
        }
    },
    components:{
        child
    }
}
</script>


//子組件:child.vue
<template>
    <div>
        {{vals}}
    </div>
</template>
<script>
export default {
      props:{ //父組件傳值 能夠是一個數組,對象
        vals:{
            type:String,//類型爲字符竄
          default:"123" //能夠設置默認值
        }
    },
}
</script>

 

2.子組件到父組件的通訊this

使用 $emit(eventname,option) 觸發事件,
參數一:自定義事件名稱,寫法,小寫或者用-鏈接,如event,event-name 不能寫駝峯寫法(eventName)
子組件給父組件傳值,能夠在子組件中使用$emit觸發事件的值傳出去,父組件經過事件監聽,獲取數據
 
可是,這裏有一個問題,
一、到底是由子組件內部主動傳數據給父組件,由父組件監聽接收(由子組件中操做決定何時傳值)
二、仍是經過父組件決定子組件何時傳值給父組件,而後再監聽接收 (由父組件中操做決定何時傳值)
兩種狀況都有
2.1 : $meit事件觸發,經過子組件內部的事件觸發自定義事件$emit
2.2 : $meit事件觸發, 能夠經過父組件操做子組件 (ref)的事件來觸發 自定義事件$emit
第一種狀況:
//父組件:parent.vue
<template>
    <div>
        <child  v-on:childevent='wathChildEvent'></child>
        <div>子組件的數據爲:{{msg}}</div>
    </div>
</template>
<script>
import child from "./child";
export default {
    data(){
        return{
            msg:""
        }
    },
    components:{
        child
    },
    methods:{
        wathChildEvent:function(vals){//直接監聽 又子組件觸發的事件,參數爲子組件的傳來的數據
            console.log(vals);//結果:這是子組件的數據,將有子組件操做觸發傳給父組件
            this.msg = vlas;
        } 
    }
}
</script>

//子組件:child.vue
<template>
    <div>
       <input type="button" value="子組件觸發" @click="target">
    </div>
</template>
<script>
export default {
    data(){
            return {
            texts:'這是子組件的數據,將有子組件操做觸發傳給父組件'
            }
    },
    methods:{
        target:function(){ //有子組件的事件觸發 自定義事件childevent
            this.$emit('childevent',this.texts);//觸發一個在子組件中聲明的事件 childEvnet
        }
    },
}
</script>

第二種狀況:spa

//父組件:parent.vue
<template>
    <div>
        <child  v-on:childevent='wathChildEvent' ref="childcomp"></child>
        <input type="button" @click="parentEnvet" value="父組件觸發" />
        <div>子組件的數據爲:{{msg}}</div>
    </div>
</template>
<script>
import child from "./child";
export default {
    data(){
        return{
            msg:""
        }
    },
    components:{
        child
    },
    methods:{
        wathChildEvent:function(vals){//直接監聽 又子組件觸發的事件,參數爲子組件的傳來的數據
            console.log(vals);//這是子組件的數據,將有子組件操做觸發傳給父組件
            this.msg = vlas;
        },
        parentEnvet:function(){
            this.$refs['childcomp'].target(); //經過refs屬性獲取子組件實例,又父組件操做子組件的方法觸發事件$meit
        }
    }
}
</script>

//子組件:child.vue
<template>
    <div>
      <!-- dothing..... -->
    </div>
</template>
<script>
export default {
    data(){
            return {
            texts:'這是子組件的數據,將有子組件操做觸發傳給父組件'
            }
    },
    methods:{
        target:function(){ //又子組件的事件觸發 自定義事件childevent
            this.$emit('childevent',this.texts);//觸發一個在子組件中聲明的事件 childEvnet
        }
    },
}
</script>

將二者狀況對比,區別就在於$emit 自定義事件的觸發是有父組件仍是子組件去觸發code

第一種,是在子組件中定義一個click點擊事件來觸發自定義事件$emit,而後在父組件監聽component

第二種,是在父組件中第一一個click點擊事件,在組件中經過refs獲取實例方法來直接觸發事件,而後在父組件中監聽

 

3.兄弟組件之間的通訊

 (1)、兄弟之間傳遞數據經過事件
 (2)、建立一個新Vue的實例,讓各個兄弟共用同一個事件機制。(關鍵點)
 (3)、傳遞數據方,經過事件觸發$emit(方法名,傳遞的數據)。
 (4)、接收數據方,在mounted()鉤子函數(掛載實例)中 觸發事件$on(方法名,callback(接收數據的數據)),此時callback函數中的this已經發生了改變,可使用箭頭函數。
//創建一個空的Vue實例,將通訊事件掛載在該實例上
//emptyVue.js
import Vue from 'vue'
export default new Vue()

//兄弟組件a:childa.vue
<template>
    <div>
        <span>A組件->{{msg}}</span>
        <input type="button" value="把a組件數據傳給b" @click ="send">
    </div>
</template>
<script>
import vmson from "./emptyVue"
export default {
    data(){
        return {
            msg:"我是a組件的數據"
        }
    },
    methods:{
        send:function(){
            vmson.$emit("aevent",this.msg)
        }
    }
}
</script>


//兄弟組件b:childb.vue
<template>
     <div>
        <span>b組件,a傳的的數據爲->{{msg}}</span>
    </div>
</template>
<script>
import vmson from "./emptyVue"
export default {
 data(){
        return {
            msg:""
        }
    },
    mounted(){
        vmson.$on("aevent",(val)=>{//監聽事件aevent,回調函數要使用箭頭函數;
            console.log(val);//打印結果:我是a組件的數據
            this.msg = val;
        })
    }
}
</script>


//父組件:parent.vue
<template>
    <div>
        <childa><childa>
        <childb></childb>
    </div>
</template>
<script>
import childa from "./childa";
import childb from "./childb";
export default {
    data(){
        return{
            msg:""
        }
    },
    components:{
        childa,
        childb
    },
  
}
</script>

 

到此,vue中的組件通訊傳值基本能夠搞定了,可是對於大型複雜的項目,建議採用vuex 狀態管理更適合....

推薦參考學習:https://vuex.vuejs.org/zh-cn/

          https://cn.vuejs.org/v2/api/#vm-emit

         https://cn.vuejs.org/v2/api/#vm-on

 

 完結。。。謝謝

相關文章
相關標籤/搜索