vue中的$emit 與$on父子組件與兄弟組件的之間通信方式
本文主要對(duì)vue 用$emit 與 $on 來(lái)進(jìn)行組件之間的數(shù)據(jù)傳輸.
主要的傳輸方式有三種:
1.父組件到子組件通信
2.子組件到父組件的通信
3.兄弟組件之間的通信
一、父組件傳值給子組件
父組件給子組件傳子,使用props
//父組件:parent.vue <template> <div> <child :vals = "msg"></child> </div> </template> <script> import child from "./child"; export default { data(){ return { msg:"我是父組件的數(shù)據(jù),將傳給子組件" } }, components:{ child } } </script> //子組件:child.vue <template> <div> {{vals}} </div> </template> <script> export default { props:{ //父組件傳值 可以是一個(gè)數(shù)組,對(duì)象 vals:{ type:String,//類型為字符竄 default:"123" //可以設(shè)置默認(rèn)值 } }, } </script>
2.子組件到父組件的通信
使用 $emit(eventname,option)
觸發(fā)事件,
參數(shù)一:自定義事件名稱,寫(xiě)法,小寫(xiě)或者用-連接,如event,event-name 不能寫(xiě)駝峰寫(xiě)法(eventName)
子組件給父組件傳值,可以在子組件中使用$emit觸發(fā)事件的值傳出去,父組件通過(guò)事件監(jiān)聽(tīng),獲取數(shù)據(jù)
但是,這里有一個(gè)問(wèn)題,
1、究竟是由子組件內(nèi)部主動(dòng)傳數(shù)據(jù)給父組件,由父組件監(jiān)聽(tīng)接收(由子組件中操作決定什么時(shí)候傳值)
2、還是通過(guò)父組件決定子組件什么時(shí)候傳值給父組件,然后再監(jiān)聽(tīng)接收 (由父組件中操作決定什么時(shí)候傳值)
兩種情況都有
2.1 : $meit事件觸發(fā),通過(guò)子組件內(nèi)部的事件觸發(fā)自定義事件$emit
2.2 : $meit事件觸發(fā), 可以通過(guò)父組件操作子組件 (ref)的事件來(lái)觸發(fā) 自定義事件$emit
第一種情況:
//父組件:parent.vue <template> <div> <child v-on:childevent='wathChildEvent'></child> <div>子組件的數(shù)據(jù)為:{{msg}}</div> </div> </template> <script> import child from "./child"; export default { data(){ return{ msg:"" } }, components:{ child }, methods:{ wathChildEvent:function(vals){//直接監(jiān)聽(tīng) 又子組件觸發(fā)的事件,參數(shù)為子組件的傳來(lái)的數(shù)據(jù) console.log(vals);//結(jié)果:這是子組件的數(shù)據(jù),將有子組件操作觸發(fā)傳給父組件 this.msg = vlas; } } } </script> //子組件:child.vue <template> <div> <input type="button" value="子組件觸發(fā)" @click="target"> </div> </template> <script> export default { data(){ return { texts:'這是子組件的數(shù)據(jù),將有子組件操作觸發(fā)傳給父組件' } }, methods:{ target:function(){ //有子組件的事件觸發(fā) 自定義事件childevent this.$emit('childevent',this.texts);//觸發(fā)一個(gè)在子組件中聲明的事件 childEvnet } }, } </script>
第二種情況:
//父組件:parent.vue <template> <div> <child v-on:childevent='wathChildEvent' ref="childcomp"></child> <input type="button" @click="parentEnvet" value="父組件觸發(fā)" /> <div>子組件的數(shù)據(jù)為:{{msg}}</div> </div> </template> <script> import child from "./child"; export default { data(){ return{ msg:"" } }, components:{ child }, methods:{ wathChildEvent:function(vals){//直接監(jiān)聽(tīng) 又子組件觸發(fā)的事件,參數(shù)為子組件的傳來(lái)的數(shù)據(jù) console.log(vals);//這是子組件的數(shù)據(jù),將有子組件操作觸發(fā)傳給父組件 this.msg = vlas; }, parentEnvet:function(){ this.$refs['childcomp'].target(); //通過(guò)refs屬性獲取子組件實(shí)例,又父組件操作子組件的方法觸發(fā)事件$meit } } } </script> //子組件:child.vue <template> <div> <!-- dothing..... --> </div> </template> <script> export default { data(){ return { texts:'這是子組件的數(shù)據(jù),將有子組件操作觸發(fā)傳給父組件' } }, methods:{ target:function(){ //又子組件的事件觸發(fā) 自定義事件childevent this.$emit('childevent',this.texts);//觸發(fā)一個(gè)在子組件中聲明的事件 childEvnet } }, } </script>
將兩者情況對(duì)比,區(qū)別就在于$emit 自定義事件的觸發(fā)是有父組件還是子組件去觸發(fā)
第一種,是在子組件中定義一個(gè)click點(diǎn)擊事件來(lái)觸發(fā)自定義事件$emit,然后在父組件監(jiān)聽(tīng)
第二種,是在父組件中第一一個(gè)click點(diǎn)擊事件,在組件中通過(guò)refs獲取實(shí)例方法來(lái)直接觸發(fā)事件,然后在父組件中監(jiān)聽(tīng)
3.兄弟組件之間的通信
(1)、兄弟之間傳遞數(shù)據(jù)通過(guò)事件
(2)、創(chuàng)建一個(gè)新Vue的實(shí)例,讓各個(gè)兄弟共用同一個(gè)事件機(jī)制。(關(guān)鍵點(diǎn))
(3)、傳遞數(shù)據(jù)方,通過(guò)事件觸發(fā)$emit(方法名,傳遞的數(shù)據(jù))。
(4)、接收數(shù)據(jù)方,在mounted()鉤子函數(shù)(掛載實(shí)例)中 觸發(fā)事件$on(方法名,callback(接收數(shù)據(jù)的數(shù)據(jù))),此時(shí)callback函數(shù)中的this已經(jīng)發(fā)生了改變,可以使用箭頭函數(shù)。
//建立一個(gè)空的Vue實(shí)例,將通信事件掛載在該實(shí)例上 //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ǔ)組件數(shù)據(jù)傳給b" @click ="send"> </div> </template> <script> import vmson from "./emptyVue" export default { data(){ return { msg:"我是a組件的數(shù)據(jù)" } }, methods:{ send:function(){ vmson.$emit("aevent",this.msg) } } } </script> //兄弟組件b:childb.vue <template> <div> <span>b組件,a傳的的數(shù)據(jù)為->{{msg}}</span> </div> </template> <script> import vmson from "./emptyVue" export default { data(){ return { msg:"" } }, mounted(){ vmson.$on("aevent",(val)=>{//監(jiān)聽(tīng)事件aevent,回調(diào)函數(shù)要使用箭頭函數(shù); console.log(val);//打印結(jié)果:我是a組件的數(shù)據(jù) 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中的組件通信傳值基本可以搞定了,但是對(duì)于大型復(fù)雜的項(xiàng)目,建議采用vuex 狀態(tài)管理更適合....
推薦參考學(xué)習(xí):https://vuex.vuejs.org/zh-cn/
https://cn.vuejs.org/v2/api/#vm-emit
https://cn.vuejs.org/v2/api/#vm-on
總結(jié)
以上所述是小編給大家介紹的vue中的$emit 與$on父子組件與兄弟組件的之間通信方式,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)歡迎給我留言,小編會(huì)及時(shí)回復(fù)大家的!
相關(guān)文章
簡(jiǎn)單聊一聊axios配置請(qǐng)求頭content-type
最近在工作中碰到一個(gè)問(wèn)題,后端提供的get請(qǐng)求的接口需要在request header設(shè)置,下面這篇文章主要給大家介紹了關(guān)于axios配置請(qǐng)求頭content-type的相關(guān)資料,需要的朋友可以參考下2022-04-04Vue首屏加載過(guò)慢出現(xiàn)白屏的6種優(yōu)化方案匯總
vue項(xiàng)目打包上線后,首次打開(kāi)會(huì)發(fā)現(xiàn)加載很慢,出現(xiàn)白屏的問(wèn)題,下面這篇文章主要給大家介紹了關(guān)于Vue首屏加載過(guò)慢出現(xiàn)白屏的6種優(yōu)化方案,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-02-02element?el-tree折疊收縮的實(shí)現(xiàn)示例
本文主要介紹了element?el-tree折疊收縮的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08Vue.js最佳實(shí)踐(五招助你成為vuejs大師)
這篇文章主要介紹了Vue.js最佳實(shí)踐,本文主要面向?qū)ο笫怯幸欢╲ue.js 編輯經(jīng)驗(yàn)的開(kāi)發(fā)者,需要的朋友可以參考下2018-05-05Vue兩個(gè)同級(jí)組件傳值實(shí)現(xiàn)
Vue組件之間是有聯(lián)系的,避免不了組件之間要互相傳值,那么如何實(shí)現(xiàn)Vue兩個(gè)同級(jí)組件傳值,本文就來(lái)介紹一下,感興趣的可以了解一下2021-07-07VUE 配置vue-devtools調(diào)試工具及安裝方法
vue-devtools是一款基于chrome瀏覽器的插件,用于vue應(yīng)用的調(diào)試,這款vue調(diào)試神器可以極大地提高我們的調(diào)試效率。幫助我們快速的調(diào)試開(kāi)發(fā)vue應(yīng)用。這篇文章主要介紹了VUE 配置vue-devtools調(diào)試工具及安裝步驟 ,需要的朋友可以參考下2018-09-09