項(xiàng)目中總是難免遇到事件擊發(fā)與接收的情況,而Vue中提供的emit擊發(fā)和on接收事件的方法又局限于父子組件的范圍內(nèi)骑歹。而對(duì)于兄弟組件之間预烙,貌似網(wǎng)上查到的都是用另一個(gè)Vue對(duì)象來(lái)轉(zhuǎn)發(fā)事件,用Vuex來(lái)傳遞數(shù)值道媚。我在想是不是也可以通過(guò)Vuex來(lái)作為事件擊發(fā)/轉(zhuǎn)發(fā)的媒介扁掸。
話不多說(shuō),上代碼:
Vuex中擊發(fā)事件最域,儲(chǔ)存事件谴分,轉(zhuǎn)發(fā)事件的方法:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
eventBus: []
},
getters: {
onEvent(state) {
return function (name) {
let index = state.eventBus.map((eb) = > {return eb.name}).indexOf(name);
if (state.eventBus.length > 0 && index >= 0) {
let result = Object.assign({}, state.eventBus[index]);
state.eventBus.splice(index, 1);
return result;
}
return null;
}
}
},
mutations: {
emitEvent(state, event) {
if (event && event.name) {
event.content = !event.content ? '' : event.content;
event.time = new Date().getTime();
state.eventBus.push(event);
}
}
}
})
對(duì)應(yīng)vue組件中接收事件的代碼:
export default {
name: 'app',
data: function () {
return {
showAlarmConfirm: false,
content: ''
}
},
computed: {
alertCont() {
return this.$store.getters.onEvent('alert');
}
},
watch: {
alertCont: function (a, b) {
if (a !== b && a) {
this.content = a.content;
this.showAlarmConfirm = true;
}
}
}
}
任何其他組件中,擊發(fā)事件的方法:
this.$store.commit('emitEvent',{name:'alert',content:'test'});
p.s.在接收事件的vue組件中watch alertCont改變情況的回調(diào)函數(shù)里镀脂,有一個(gè)a!==b&&a的判斷狸剃,這是因?yàn)樵趙atch的時(shí)候,alertCont每次改變狗热,會(huì)引發(fā)對(duì)應(yīng)watch回調(diào)函數(shù)執(zhí)行兩次钞馁,第一次是alertCont從null變?yōu)檎V担╝為正常值,b為null)匿刮,第二次alertCont的值沒(méi)有改變(a僧凰,b都是正常值),之后會(huì)又第三次執(zhí)行回調(diào)熟丸,這時(shí)(a為null训措,b為正常值),為了將這種情況過(guò)濾到只執(zhí)行一次光羞,于是加了這樣的判斷绩鸣。
個(gè)人推測(cè)第二次執(zhí)行回調(diào)時(shí),是Vue框架內(nèi)部的賦值機(jī)制所導(dǎo)致的纱兑。
如果有什么想法呀闻,歡迎留言討論
2018-01-22:
這種方法只是組件間的值傳遞,在接收數(shù)據(jù)的位置使用了相對(duì)麻煩的watch監(jiān)聽(tīng)computed計(jì)算屬性潜慎,并非真正意義上的事件擊發(fā)與接收捡多。
這種方法一次只能處理一個(gè)事件,如果在同一個(gè)位置提交多個(gè)事件的話铐炫,實(shí)際上只有一個(gè)事件被轉(zhuǎn)發(fā)(其他的事件留在了store當(dāng)中)垒手,所以這個(gè)方法就暫時(shí)停留在非常簡(jiǎn)單的應(yīng)用場(chǎng)景,復(fù)雜的情況下會(huì)出現(xiàn)意想不到的結(jié)果倒信。
經(jīng)過(guò)查閱資料科贬,瀏覽器一般至少是有三個(gè)線程在運(yùn)行的:JavaScript引擎線程、DOM更新線程鳖悠、事件線程榜掌。而在JavaScript內(nèi)部又是單線程運(yùn)行的(promise优妙、setTimeout和setInterval其實(shí)算是偽多線程),想要再啟動(dòng)一個(gè)線程來(lái)模擬事件的emit和on就有點(diǎn)乏力了唐责。
如果有什么好的想法也歡迎留言交流討論:D