$emit和$on能夠實現組件之間的傳值,咱們知道父組件傳值給子組件使用props,可是不容許子組件傳值給父組件,這時候使用這個就能夠實現了。這也能夠用在兄弟組件之間的通訊。javascript
注意:$emit和$on的事件必須在一個公共的實例上,纔可以觸發。vue
例子:我要實現某個系統的通信錄功能,在web端咱們能夠使用基於jQuery的ztree插件實現目錄的展示,可是在vuejs框架裏面,tree目錄須要經過遞歸組件實現。
一、如今有兩個組件,父組件contact_index.vue,子組件cust_tree.vuejava
二、點擊父組件裏面的選擇銀行,跳出銀行樹目錄結構(使用vuejs的遞歸組件實現),這裏面須要作兩種傳值:
(1)父組件經過props將樹目錄的數據list傳到子組件中造成目錄結構的展現;
(2)子組件裏面經過點擊相應的銀行請求查詢銀行的通信錄,這裏面須要將點擊的銀行的機構代碼回傳給父組件,父組件接收後經過input將機構代碼提交給後臺請求查詢;web
第一種是父組件給子組件傳值使用props便可,如今咱們來談談第二種狀況,如何將子組件的值回傳給父組件。框架
網上百度千篇一概全是使用$emit來實現,但是都有一個嚴重的誤區沒有給別人說明,開始我都按照搜索的結果進行操做,都會出現子組件$emit後父組件沒有監聽到函數的變化,研究了很久才發現$emit和$on的事件必須在一個公共的實例上,纔可以觸發。個人操做以下:函數
首先在src目錄下新加bus.js做爲一個公共的實例this
import Vue from 'vue' export var bus = new Vue()
其次,父組件在created裏面定義$on監聽事件spa
//父組件與子組件都要import bus.js import {bus} from '../../bus.js'
created(){ bus.$on('custTreeSay',(id)=>{ //監聽傳值--機構代碼 this.instCode = id; //關閉彈窗 this.popupVisibleTree = false; //調用查詢方法刷新通信錄列表 this.query(); }); bus.$on('custTreeSayName',(name)=>{ //監聽傳值--機構名稱 this.instName = name; }); }
最後,在子組件中定義點擊事件,調用父組件方法經過$emit將相應值傳給父組件插件
<span @click="propInstCode(model);propInstName(model)"> {{model.name}} </span>
<script type="text/javascript"> import {bus} from '../../bus.js' export default { props: ['model'],//這裏經過props接收父組件的傳值 //method鉤子定義傳值方法,這邊須要傳不一樣的值 methods: { //經過總線將值傳給父組件 propInstCode:function (model) { //$emit觸發當前實例事件 bus.$emit('custTreeSay',this.model.id); }, propInstName:function (model) { bus.$emit('custTreeSayName',this.model.name); } }, }
這樣就實現了子組件能經過$emit將值傳給bus在傳給父組件了,最後是經過傳的機構代碼傳給提交給後臺查詢的,可是咱們同時也須要相應的機構名字來給客戶展示,因此這裏面只須要設置兩個input就好了,機構代碼的input隱藏起來,須要傳值,另外的機構名稱的input顯示出來就能夠了,以下:code
//將點擊跳出目錄選擇的方法放到顯示的機構選擇就能夠了 <div class="query_condition_item"> <label>選擇機構</label> <input name="instName" v-model="instName" readonly @click="showTree()"> </div> <div class="query_condition_item"> <input name="instCode" v-model="instCode" hidden> </div>
這篇文章就到這裏了,我將我開發遇到的一些問題經驗記錄下來,也但願可以幫到你們!!