最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue3.0組件通信mitt源碼ts實例解析

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

背景介紹

近期業(yè)務開發(fā),會想起之前做的兩個組件的通信,社區(qū)推薦使用一個迷你庫miit (200b), 因為vue3開發(fā)中沒有了 EventBus 跨組件通信,這個替代的方案 mitt.js,原理還是 EventBus

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

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

使用方法

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

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

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

// 組件 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)聽
onMounted(()=>{ mitt.on('search-change',(obj)=> { do sth} })
// off 監(jiān)聽 
onUnmounted(()=>{ mitt.off('search-change', ()=> { do sth } })
</script>

源碼分析

一行行看,看懂每一行的寫法和整體思想

export type EventType = string | symbol;
// 源碼第一段分析
export 一個類型別名 EventType,上面例子中我們mitter.emit('search-change', obj); 
search-change就是一個string類型,
同時EventType也可以是聯合類型symbol,為了保證事件的唯一性
export type Handler<T = unknown> = (event: T) => void;
export type WildcardHandler<T = Record<string, unknown>> = (
    type: keyof T,
    event: T[keyof T]
) => void;
// 源碼第二段分析
使用類型別名定義函數Handler,Handler接受一個泛型參數<T>,默認值是unknown
export type EventHandlerList<T = unknown> = Array<Handler<T>>;
export type WildCardEventHandlerList<T = Record<string, unknown>>
= Array<WildcardHandler<T>>;
// 源碼第三段分析
當前所有注冊的事件列表類型定義  Array<T>數組的泛型定義
export type EventHandlerMap<Events extends Record<EventType, unknown>>
= Map<keyof Events | '*',EventHandlerList<Events[keyof Events]> 
| WildCardEventHandlerList<Events>>;
// 源碼第四段分析
這里是事件類型及其對應的事件處理程序的映射Map做了定義,使用extend繼承一個Record對象,
該對象的兩個參數一個是限制為Events上已知的公共屬性名的聯合或者*, 
另外一個參數要是是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用于下面一段核心代碼的返回值類型定義,這個interface定義了具體函數的結構類型
Emitter這個類型的泛型是Events繼承一個Record對象,該對象的key為EventType,value為unknown
導出了一個 mitt([all])函數,調用該函數返回一個 Emitter,該對象包含all、
on(type, handler)、off(type, [handler])和emit(type, [evt])這幾個屬性
/**
* 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!);
                });
             }
        }
    };
}

核心代碼主要實現就是:

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

2.on(type, handler)定義函數 on來注冊事件,以type為屬性,[handler]為屬性值,
存儲在 all 中,屬性值為數組的原因是可能存在監(jiān)聽一個事件,多個處理程序

3.off(type, [handler])來取消某個事件的某個處理函數,根據 type 找到對應的事件處理數組,
對比 handler 是否相等,相等則刪除該處理函數,不傳則刪除該事件的全部處理函數

4.emit(type, [evt])來派發(fā)事件,根據 type 找到對應的事件處理數組并依次執(zhí)行,傳入參數 evt(對象最好,傳多個參數只會取到第一個)

以上就是Vue3.0組件通信mitt源碼ts實例解析的詳細內容,更多關于Vue3.0組件通信mitt ts的資料請關注腳本之家其它相關文章!

相關文章

  • webpack項目中使用vite加速的兼容模式詳解

    webpack項目中使用vite加速的兼容模式詳解

    這篇文章主要為大家介紹了webpack項目中使用vite加速的兼容模式示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • Vue組件重新渲染(組件重載)的3種實現方式

    Vue組件重新渲染(組件重載)的3種實現方式

    這篇文章主要介紹了Vue組件重新渲染(組件重載)的3種實現方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • 關于Vue3中defineProps用法圖文詳解

    關于Vue3中defineProps用法圖文詳解

    在vue3中組件傳參有很多種方式,和v2大差不差,但是有的地方還是有很多的區(qū)別,下面這篇文章主要給大家介紹了關于Vue3中defineProps用法的相關資料,需要的朋友可以參考下
    2022-11-11
  • 淺談Vant-list?上拉加載及下拉刷新的問題

    淺談Vant-list?上拉加載及下拉刷新的問題

    這篇文章主要介紹了淺談Vant-list?上拉加載及下拉刷新的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • 前端項目vue3/React如何使用pako庫解壓縮后端返回gzip數據

    前端項目vue3/React如何使用pako庫解壓縮后端返回gzip數據

    pako是一個流行的JS庫,用于在瀏覽器中進行數據壓縮和解壓縮操作,它提供了對常見的壓縮算法的實現,使開發(fā)者能夠在客戶端上輕松進行數據壓縮和解壓縮,這篇文章主要介紹了前端項目vue3/React使用pako庫解壓縮后端返回gzip數據,需要的朋友可以參考下
    2024-07-07
  • 在vue.js中使用JSZip實現在前端解壓文件的方法

    在vue.js中使用JSZip實現在前端解壓文件的方法

    今天小編就為大家分享一篇在vue.js中使用JSZip實現在前端解壓文件的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09
  • 一篇文章帶你了解vue路由

    一篇文章帶你了解vue路由

    這篇文章主要為大家詳細介紹了vue的路由,路由的本質就是一種對應關系,比如說我們在url地址中輸入我們要訪問的url地址之后,瀏覽器要去請求這個url地址對應的資源,本文具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • vue uniapp實現分段器效果

    vue uniapp實現分段器效果

    這篇文章主要為大家詳細介紹了vue uniapp實現分段器效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • 圖文講解用vue-cli腳手架創(chuàng)建vue項目步驟

    圖文講解用vue-cli腳手架創(chuàng)建vue項目步驟

    本次小編給大家?guī)淼氖顷P于用vue-cli腳手架創(chuàng)建vue項目步驟講解內容,有需要的朋友們可以學習下。
    2019-02-02
  • 使用vue3重構拼圖游戲的實現示例

    使用vue3重構拼圖游戲的實現示例

    這篇文章主要介紹了使用vue3重構拼圖游戲的實現示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-01-01

最新評論

平遥县| 龙南县| 古交市| 中方县| 胶南市| 汾西县| 辛集市| 重庆市| 大英县| 依兰县| 泗水县| 吴桥县| 屏东市| 湖州市| 哈尔滨市| 淮南市| 河曲县| 宁武县| 芜湖市| 双城市| 卓资县| 麟游县| 紫阳县| 渑池县| 花莲县| 元谋县| 宁阳县| 二连浩特市| 太原市| 秦皇岛市| 饶平县| 墨竹工卡县| 江达县| 伊金霍洛旗| 东兴市| 乐平市| 洛宁县| 香格里拉县| 牟定县| 奉化市| 张家口市|