欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue3.0組件通信mitt源碼ts實(shí)例解析

 更新時(shí)間:2022年11月23日 10:12:24   作者:碩兒的編程之路  
這篇文章主要為大家介紹了Vue3.0組件通信mitt源碼ts實(shí)例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

背景介紹

近期業(yè)務(wù)開(kāi)發(fā),會(huì)想起之前做的兩個(gè)組件的通信,社區(qū)推薦使用一個(gè)迷你庫(kù)miit (200b), 因?yàn)関ue3開(kāi)發(fā)中沒(méi)有了 EventBus 跨組件通信,這個(gè)替代的方案 mitt.js,原理還是 EventBus

EventBus在多個(gè)組件之間進(jìn)行事件通信的場(chǎng)景下還是比較有用的,通過(guò)監(jiān)聽(tīng)事件和觸發(fā)事件,可以在訂閱者和發(fā)布者之間解耦,實(shí)現(xiàn)一個(gè)常規(guī)的eventBus也比較簡(jiǎn)單

以上實(shí)例是組件B想和組件C通信,但是mitt不管組件嵌套多深都可以直接拿來(lái)用

使用方法

先安裝 npm i mitt -S到項(xiàng)目中,然后像以前封裝EventBus一樣封裝

// 可以在項(xiàng)目目錄utils下封裝一個(gè)event.js
import mitt from 'mitt'
const mitt = mitt()
export default mitt

業(yè)務(wù)邏輯組件中通信使用

// 組件 A
<script setup>
import mitt from '@/utils/event.js'
function handleChange(obj) {
    mitter.emit('search-change', obj);
}
</script>
// 組件 B 
<script setup>
import mitt from '@/utils/event.js'
import { onUnmounted ,onMounted} from 'vue'
// 監(jiān)聽(tīng)
onMounted(()=>{ mitt.on('search-change',(obj)=> { do sth} })
// off 監(jiān)聽(tīng) 
onUnmounted(()=>{ mitt.off('search-change', ()=> { do sth } })
</script>

源碼分析

一行行看,看懂每一行的寫(xiě)法和整體思想

export type EventType = string | symbol;
// 源碼第一段分析
export 一個(gè)類型別名 EventType,上面例子中我們mitter.emit('search-change', obj); 
search-change就是一個(gè)string類型,
同時(shí)EventType也可以是聯(lián)合類型symbol,為了保證事件的唯一性
export type Handler<T = unknown> = (event: T) => void;
export type WildcardHandler<T = Record<string, unknown>> = (
    type: keyof T,
    event: T[keyof T]
) => void;
// 源碼第二段分析
使用類型別名定義函數(shù)Handler,Handler接受一個(gè)泛型參數(shù)<T>,默認(rèn)值是unknown
export type EventHandlerList<T = unknown> = Array<Handler<T>>;
export type WildCardEventHandlerList<T = Record<string, unknown>>
= Array<WildcardHandler<T>>;
// 源碼第三段分析
當(dāng)前所有注冊(cè)的事件列表類型定義  Array<T>數(shù)組的泛型定義
export type EventHandlerMap<Events extends Record<EventType, unknown>>
= Map<keyof Events | '*',EventHandlerList<Events[keyof Events]> 
| WildCardEventHandlerList<Events>>;
// 源碼第四段分析
這里是事件類型及其對(duì)應(yīng)的事件處理程序的映射Map做了定義,使用extend繼承一個(gè)Record對(duì)象,
該對(duì)象的兩個(gè)參數(shù)一個(gè)是限制為Events上已知的公共屬性名的聯(lián)合或者*, 
另外一個(gè)參數(shù)要是是EventHandlerList或者是WildCardEventHandlerList
export interface Emitter<Events extends Record<EventType, unknown>> {
    all: EventHandlerMap<Events>;
    on<Key extends keyof Events>(type: Key, handler: Handler<Events[Key]>)
    : void;
    on(type: '*', handler: WildcardHandler<Events>):void;
    off<Key extends keyof Events>(type: Key, handler?:
    Handler<Events[Key]>): void;
    off(type: '*', handler: WildcardHandler<Events>):void;
    emit<Key extends keyof Events>(type: Key, event: Events[Key]):void;
    emit<Key extends keyof Events>(type: undefined extends Events[Key] ? 
    Key : never):void;
}
// 源碼第五段分析
interface Emitter用于下面一段核心代碼的返回值類型定義,這個(gè)interface定義了具體函數(shù)的結(jié)構(gòu)類型
Emitter這個(gè)類型的泛型是Events繼承一個(gè)Record對(duì)象,該對(duì)象的key為EventType,value為unknown
導(dǎo)出了一個(gè) mitt([all])函數(shù),調(diào)用該函數(shù)返回一個(gè) Emitter,該對(duì)象包含all、
on(type, handler)、off(type, [handler])和emit(type, [evt])這幾個(gè)屬性
/**
* Mitt: Tiny (~200b) functional event emitter / pubsub.
* @name mitt
* @returns {Mitt}
*/
export default function mitt<Events extends Record<EventType, unknown>>(
all?: EventHandlerMap<Events>
): Emitter<Events> {
    type GenericEventHandler =
    | Handler<Events[keyof Events]>
    | WildcardHandler<Events>;
    all = all || new Map();
    return {
        /**
        * A Map of event names to registered handler functions.
        */
        all,
        /**
        * Register an event handler for the given type.
        * @param {string|symbol} type Type of event to listen for, or `'*'` for all events
        * @param {Function} handler Function to call in response to given event
        * @memberOf mitt
        */
        on<Key extends keyof Events>(type: Key, handler: GenericEventHandler) {
            const handlers: Array<GenericEventHandler> | undefined =
            all!.get(type);
            if (handlers) {
            handlers.push(handler);
            } else {
                all!.set(type, [handler] as EventHandlerList<
                Events[keyof Events]>);
            }
        },
        /**
        * Remove an event handler for the given type.
        * If `handler` is omitted, all handlers of the given type are removed.
        * @param {string|symbol} type Type of event to unregister `handler` from (`'*'` to remove a wildcard handler)
        * @param {Function} [handler] Handler function to remove
        * @memberOf mitt
        */
        off<Key extends keyof Events>( type: Key,
        handler?: GenericEventHandler
        ) {
            const handlers: Array<GenericEventHandler> | undefined =
            all!.get(type);
            if (handlers) {
                if (handler) {
                    handlers.splice(handlers.indexOf(handler) >>> 0, 1);
                } else {
                    all!.set(type, []);
                }
            }
        },
        /**
        * Invoke all handlers for the given type.
        * If present, `'*'` handlers are invoked after type-matched handlers.
        *
        * Note: Manually firing '*' handlers is not supported.
        *
        * @param {string|symbol} type The event type to invoke
        * @param {Any} [evt] Any value (object is recommended and powerful), passed to each handler
        * @memberOf mitt
        */
        emit<Key extends keyof Events>(type: Key, evt?: Events[Key]) {
            let handlers = all!.get(type);
            if (handlers) {
                (handlers as EventHandlerList<Events[keyof Events]>)
                .slice()
                .map((handler) => {
                    handler(evt!);
                });
            }
            handlers = all!.get('*');
            if (handlers) {
                (handlers as WildCardEventHandlerList<Events>)
                .slice()
                .map((handler) => {
                    handler(type, evt!);
                });
             }
        }
    };
}

核心代碼主要實(shí)現(xiàn)就是:

1.all = all || new Map() mitt 支持傳入 all 參數(shù)用來(lái)存儲(chǔ)事件類型和事件處理函
數(shù)的映射Map,如果不傳,就 `new Map()`賦值給 all

2.on(type, handler)定義函數(shù) on來(lái)注冊(cè)事件,以type為屬性,[handler]為屬性值,
存儲(chǔ)在 all 中,屬性值為數(shù)組的原因是可能存在監(jiān)聽(tīng)一個(gè)事件,多個(gè)處理程序

3.off(type, [handler])來(lái)取消某個(gè)事件的某個(gè)處理函數(shù),根據(jù) type 找到對(duì)應(yīng)的事件處理數(shù)組,
對(duì)比 handler 是否相等,相等則刪除該處理函數(shù),不傳則刪除該事件的全部處理函數(shù)

4.emit(type, [evt])來(lái)派發(fā)事件,根據(jù) type 找到對(duì)應(yīng)的事件處理數(shù)組并依次執(zhí)行,傳入?yún)?shù) evt(對(duì)象最好,傳多個(gè)參數(shù)只會(huì)取到第一個(gè))

以上就是Vue3.0組件通信mitt源碼ts實(shí)例解析的詳細(xì)內(nèi)容,更多關(guān)于Vue3.0組件通信mitt ts的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Vue利用computer解決單項(xiàng)數(shù)據(jù)流的問(wèn)題詳解

    Vue利用computer解決單項(xiàng)數(shù)據(jù)流的問(wèn)題詳解

    Vue 是一個(gè)非常流行和強(qiáng)大的前端框架,它讓我們可以用簡(jiǎn)潔和優(yōu)雅的方式來(lái)構(gòu)建用戶界面,今天我們來(lái)分享一個(gè) Vue 中非常經(jīng)典的問(wèn)題,也是一個(gè)非常實(shí)用的技巧,希望對(duì)大家有所幫助
    2023-07-07
  • 關(guān)于vuex的學(xué)習(xí)實(shí)踐筆記

    關(guān)于vuex的學(xué)習(xí)實(shí)踐筆記

    vuex是vue的狀態(tài)管理模式,主要可以解決父子組件嵌套層數(shù)較多,或者兄弟組件之間需要維護(hù)同一個(gè)狀態(tài)的情況。下面這篇文章主要給大家介紹了關(guān)于學(xué)習(xí)vuex的相關(guān)資料,需要的朋友可以參考學(xué)習(xí),下面來(lái)一起看看吧。
    2017-04-04
  • Vue首評(píng)加載速度及白屏?xí)r間優(yōu)化詳解

    Vue首評(píng)加載速度及白屏?xí)r間優(yōu)化詳解

    這篇文章主要介紹了vue項(xiàng)目?jī)?yōu)化首評(píng)加載速度,以及白屏?xí)r間過(guò)久的問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-09-09
  • 解決vue+router路由跳轉(zhuǎn)不起作用的一項(xiàng)原因

    解決vue+router路由跳轉(zhuǎn)不起作用的一項(xiàng)原因

    這篇文章主要介紹了解決vue+router路由跳轉(zhuǎn)不起作用的一項(xiàng)原因,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-07-07
  • vue配置nprogress實(shí)現(xiàn)頁(yè)面頂部進(jìn)度條

    vue配置nprogress實(shí)現(xiàn)頁(yè)面頂部進(jìn)度條

    這篇文章主要為大家詳細(xì)介紹了vue配置nprogress實(shí)現(xiàn)頁(yè)面頂部進(jìn)度條,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-09-09
  • Vue切換div顯示隱藏,多選,單選代碼解析

    Vue切換div顯示隱藏,多選,單選代碼解析

    這篇文章主要介紹了Vue切換div顯示隱藏,多選,單選代碼解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07
  • vue高德地圖之玩轉(zhuǎn)周邊

    vue高德地圖之玩轉(zhuǎn)周邊

    vue高德地圖,帶你玩轉(zhuǎn)周邊,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • vue.js之vue-cli腳手架的搭建詳解

    vue.js之vue-cli腳手架的搭建詳解

    本篇文章主要介紹了vue.js之vue-cli腳手架的搭建詳解,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • Vue3使用dayjs以及dayjs日期工具類詳解

    Vue3使用dayjs以及dayjs日期工具類詳解

    這篇文章主要介紹了Vue3使用dayjs以及dayjs日期工具類,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • vue響應(yīng)式更新機(jī)制及不使用框架實(shí)現(xiàn)簡(jiǎn)單的數(shù)據(jù)雙向綁定問(wèn)題

    vue響應(yīng)式更新機(jī)制及不使用框架實(shí)現(xiàn)簡(jiǎn)單的數(shù)據(jù)雙向綁定問(wèn)題

    vue是一款具有響應(yīng)式更新機(jī)制的框架,既可以實(shí)現(xiàn)單向數(shù)據(jù)流也可以實(shí)現(xiàn)數(shù)據(jù)的雙向綁定。這篇文章主要介紹了vue響應(yīng)式更新機(jī)制及不使用框架實(shí)現(xiàn)簡(jiǎn)單的數(shù)據(jù)雙向綁定問(wèn)題,需要的朋友可以參考下
    2019-06-06

最新評(píng)論