巧用Vue Mixins實現(xiàn)跨級組件通信(Event Bus)

眾所周知抖甘,在我們現(xiàn)代開發(fā)中必不可少要用到Vue或者React, 那么我們一般父子通信一般會用Props, 雖然官方也會說兩個同級兄弟組件你可以傳到同級父組件然后分發(fā),但是這樣的效率實在令人捉急召噩,層級一多你就蛋疼了(react官方出的context也是為了解決此類問題),既然都是單頁應(yīng)用逸爵,我們搞個事件監(jiān)聽和傳遞不就行了

在以前就有

element.addEventListener('click;', function(){})

首先我們需要借助發(fā)布訂閱實現(xiàn)幾個關(guān)鍵api具滴,on / off / emit
他的原理也相當(dāng)容易理解,我們維護(hù)一個事件隊列师倔,如果我們用一個key去增加/觸發(fā)事件函數(shù)獲得所需要的值构韵,這樣就完成了我們跨組件數(shù)據(jù)傳遞的需求

Event.js

class EventEmitter {
    constructor() {
        this.handersArr = {}
    }
    on(eventType, handle) {
        this.handersArr[eventType] = this.handersArr[eventType] || []
        this.handersArr[eventType].push(handle)
    }

    emit(eventType, ...args) {
        if (Array.isArray(this.handersArr[eventType])) {
            this.handersArr[eventType].forEach((item) => {
                item(...args)
            })
        }
    }

    off(eventType) {
        this.handersArr[eventType] && delete this.handersArr[eventType]
    }
}

export default EventEmitter

當(dāng)然這樣我們就完成了超級簡單的事件管理器, 但是這里我們想把它用在vue上會需要做這么幾個事情,在created接收其他組件的事件(如果有)趋艘,同比react就是componentDidMount 然后在destoryed階段(同比react就是componentWillUnmount)把這個事件摧毀疲恢,嗯,如果每次這么做就有點不夠先進(jìn)瓷胧,而且和其他業(yè)務(wù)代碼揉合在一起显拳,不科學(xué)

那我們可以在Event.js搞點事情,

    bindVue(handlers) {
        const _this = this
        let handlersWithVue = {}
        return {
            created() {
               for (const [event, _handler] of Object.entries(handlers)) {
                   const handler = _handler.bind(this) // 把_handler的this綁定到vue調(diào)用環(huán)境中去
                   _this.on(event, handler)
                   handlersWithVue[event] =  handler
               } 
            },

            beforeDestroy() {
                _this.off(handlersWithVue)
            }
        }
    }

這里涉及到一個奇技淫巧搓萧,vue的mixins特征杂数,簡單暴力來說,它可以把你需要定制的vue的js部分的邏輯全部塞進(jìn)你的業(yè)務(wù).js里面瘸洛,并起到作用揍移,咦...這上面說的不就成了。

import EventBus from '../util/bus.js'
export default {
    mixins: [EventBus.bindVue({
         changeText(value) {  // 這里就是on方法啦
              this.msg = value
         }
    })],


   [emit:]  EventBus.emit({changeText: 666})

當(dāng)然你會問React怎么實現(xiàn)反肋,因為react真的是class那伐,所以你拿到component真的就是標(biāo)準(zhǔn)對象,所以react的處理更方便點石蔗,直接把我們那個bindVue換成這個就成罕邀,react建議在constructor里面on監(jiān)聽(其實我們項目還有個hooks的實現(xiàn)23333),把我們需要的事件在componentDidMount執(zhí)行养距,componentWillUnmount銷毀

    bindComponent(component, handlers) {
        const didMount = component.componentDidMount
        const willUnmount = component.componentWillUnmount

        component.componentDidMount = () => {
            this.on(handlers)
            if (didMount) {
                return didMount.apply(component)
            }
        }

        component.componentWillUnmount = () => {
            this.off(handlers)
            if (willUnmount) {
                return willUnmount.apply(component)
            }
        }
    }

其實這里正好運用了JavaScript事件驅(qū)動和單線程的特點诉探,比較復(fù)雜的是,你要注意this的指向铃在,這里確實還是挺亂的,一不小心就不知道操作的是誰的this了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末定铜,一起剝皮案震驚了整個濱河市阳液,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌揣炕,老刑警劉巖帘皿,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異畸陡,居然都是意外死亡鹰溜,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門丁恭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來曹动,“玉大人,你說我怎么就攤上這事牲览∧钩拢” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵第献,是天一觀的道長贡必。 經(jīng)常有香客問我,道長庸毫,這世上最難降的妖魔是什么仔拟? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮飒赃,結(jié)果婚禮上利花,老公的妹妹穿的比我還像新娘。我一直安慰自己盒揉,他們只是感情好晋被,可當(dāng)我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著刚盈,像睡著了一般羡洛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上藕漱,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天欲侮,我揣著相機與錄音,去河邊找鬼肋联。 笑死威蕉,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的橄仍。 我是一名探鬼主播韧涨,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼牍戚,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了虑粥?” 一聲冷哼從身側(cè)響起如孝,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎娩贷,沒想到半個月后第晰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡彬祖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年茁瘦,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片储笑。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡甜熔,死狀恐怖愉舔,靈堂內(nèi)的尸體忽然破棺而出锨络,到底是詐尸還是另有隱情屡拨,我是刑警寧澤迁沫,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布婆瓜,位于F島的核電站榜苫,受9級特大地震影響近迁,放射性物質(zhì)發(fā)生泄漏代嗤。R本人自食惡果不足惜窄陡,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一炕淮、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧跳夭,春花似錦涂圆、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至颈抚,卻和暖如春踩衩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背贩汉。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工驱富, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人匹舞。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓褐鸥,卻偏偏與公主長得像,于是被迫代替她去往敵國和親赐稽。 傳聞我的和親對象是個殘疾皇子叫榕,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容