diff --git a/CHANGELOG.zh_CN.md b/CHANGELOG.zh_CN.md index 264ff9bb450..af4620fa40d 100644 --- a/CHANGELOG.zh_CN.md +++ b/CHANGELOG.zh_CN.md @@ -7,6 +7,8 @@ ### ⚡ Performance Improvements - **Locale** 合并多语言文件,减少文件数量 +- **Utils** Mitt 默认导出由 `Class` 改为 `Function` +- **Axios** `isTransformRequestResult`更名为`isTransformResponse` ### ✨ Features diff --git a/package.json b/package.json index e0cacaf29a6..3be00ad7a78 100644 --- a/package.json +++ b/package.json @@ -111,7 +111,7 @@ "lint-staged": "^11.0.0", "postcss": "^8.3.5", "prettier": "^2.3.1", - "pretty-quick": "^3.1.0", + "pretty-quick": "^3.1.1", "rimraf": "^3.0.2", "rollup-plugin-visualizer": "5.5.0", "stylelint": "^13.13.1", @@ -120,7 +120,7 @@ "stylelint-order": "^4.1.0", "ts-jest": "^27.0.3", "ts-node": "^10.0.0", - "typescript": "4.3.3", + "typescript": "4.3.4", "vite": "2.3.7", "vite-plugin-compression": "^0.2.5", "vite-plugin-html": "^2.0.7", diff --git a/src/components/SimpleMenu/src/components/Menu.vue b/src/components/SimpleMenu/src/components/Menu.vue index f7a3c2ae375..e3f886ca8ad 100644 --- a/src/components/SimpleMenu/src/components/Menu.vue +++ b/src/components/SimpleMenu/src/components/Menu.vue @@ -22,7 +22,7 @@ import { useDesign } from '/@/hooks/web/useDesign'; import { propTypes } from '/@/utils/propTypes'; import { createSimpleRootMenuContext } from './useSimpleMenuContext'; - import Mitt from '/@/utils/mitt'; + import mitt from '/@/utils/mitt'; export default defineComponent({ name: 'Menu', props: { @@ -44,7 +44,7 @@ }, emits: ['select', 'open-change'], setup(props, { emit }) { - const rootMenuEmitter = new Mitt(); + const rootMenuEmitter = mitt(); const instance = getCurrentInstance(); const currentActiveName = ref(''); diff --git a/src/components/SimpleMenu/src/components/SubMenuItem.vue b/src/components/SimpleMenu/src/components/SubMenuItem.vue index 25aff2adcc0..0cc91229ddf 100644 --- a/src/components/SimpleMenu/src/components/SubMenuItem.vue +++ b/src/components/SimpleMenu/src/components/SubMenuItem.vue @@ -77,7 +77,7 @@ import Icon from '/@/components/Icon'; import { Popover } from 'ant-design-vue'; import { isBoolean, isObject } from '/@/utils/is'; - import Mitt from '/@/utils/mitt'; + import mitt from '/@/utils/mitt'; const DELAY = 200; export default defineComponent({ @@ -114,7 +114,7 @@ const { prefixCls } = useDesign('menu'); - const subMenuEmitter = new Mitt(); + const subMenuEmitter = mitt(); const { rootMenuEmitter } = useSimpleRootMenuContext(); diff --git a/src/components/SimpleMenu/src/components/useSimpleMenuContext.ts b/src/components/SimpleMenu/src/components/useSimpleMenuContext.ts index a79882f7c07..d6e21036c2d 100644 --- a/src/components/SimpleMenu/src/components/useSimpleMenuContext.ts +++ b/src/components/SimpleMenu/src/components/useSimpleMenuContext.ts @@ -1,9 +1,9 @@ import type { InjectionKey, Ref } from 'vue'; import { createContext, useContext } from '/@/hooks/core/useContext'; -import Mitt from '/@/utils/mitt'; +import mitt from '/@/utils/mitt'; export interface SimpleRootMenuContextProps { - rootMenuEmitter: Mitt; + rootMenuEmitter: typeof mitt; activeName: Ref; } diff --git a/src/logics/mitt/routeChange.ts b/src/logics/mitt/routeChange.ts index 9b7d9e04fd1..335ffcc73e2 100644 --- a/src/logics/mitt/routeChange.ts +++ b/src/logics/mitt/routeChange.ts @@ -2,11 +2,11 @@ * Used to monitor routing changes to change the status of menus and tabs. There is no need to monitor the route, because the route status change is affected by the page rendering time, which will be slow */ -import Mitt from '/@/utils/mitt'; +import mitt from '/@/utils/mitt'; import type { RouteLocationNormalized } from 'vue-router'; import { getRawRoute } from '/@/utils'; -const mitt = new Mitt(); +const emitter = mitt(); const key = Symbol(); @@ -14,7 +14,7 @@ let lastChangeTab: RouteLocationNormalized; export function setRouteChange(lastChangeRoute: RouteLocationNormalized) { const r = getRawRoute(lastChangeRoute); - mitt.emit(key, r); + emitter.emit(key, r); lastChangeTab = r; } @@ -22,10 +22,10 @@ export function listenerRouteChange( callback: (route: RouteLocationNormalized) => void, immediate = true ) { - mitt.on(key, callback); + emitter.on(key, callback); immediate && lastChangeTab && callback(lastChangeTab); } export function removeTabChangeListener() { - mitt.clear(); + emitter.clear(); } diff --git a/src/utils/mitt.ts b/src/utils/mitt.ts index 12ffb082caa..bb5f03d1f52 100644 --- a/src/utils/mitt.ts +++ b/src/utils/mitt.ts @@ -1,73 +1,92 @@ /** - * Mitt: Tiny functional event emitter / pubsub - * - * @name mitt - * @param {Array} [all] Optional array of event names to registered handler functions - * @returns {Function} The function's instance + * https://github.com/developit/mitt */ -export default class Mitt { - private cache: Map void>>; - constructor(all = []) { - // A Map of event names to registered handler functions. - this.cache = new Map(all); - } - once(type: string | Symbol, handler: Fn) { - const decor = (...args: any[]) => { - handler && handler.apply(this, args); - this.off(type, decor); - }; - this.on(type, decor); - return this; - } +export type EventType = string | symbol; + +// An event handler can take an optional event argument +// and should not return a value +export type Handler = (event?: T) => void; +export type WildcardHandler = (type: EventType, event?: any) => void; + +// An array of all currently registered event handlers for a type +export type EventHandlerList = Array; +export type WildCardEventHandlerList = Array; + +// A map of event types and their corresponding event handlers. +export type EventHandlerMap = Map; + +export interface Emitter { + all: EventHandlerMap; + + on(type: EventType, handler: Handler): void; + on(type: '*', handler: WildcardHandler): void; + + off(type: EventType, handler: Handler): void; + off(type: '*', handler: WildcardHandler): void; + + emit(type: EventType, event?: T): void; + emit(type: '*', event?: any): void; +} + +/** + * Mitt: Tiny (~200b) functional event emitter / pubsub. + * @name mitt + * @returns {Mitt} + */ +export default function mitt(all?: EventHandlerMap): Emitter { + all = all || new Map(); - /** - * 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 - */ - on(type: string | Symbol, handler: Fn) { - const handlers = this.cache?.get(type); - const added = handlers && handlers.push(handler); - if (!added) { - this.cache.set(type, [handler]); - } - } + return { + /** + * A Map of event names to registered handler functions. + */ + all, - /** - * Remove an event handler for the given type. - * - * @param {string|symbol} type Type of event to unregister `handler` from, or `"*"` - * @param {Function} handler Handler function to remove - */ - off(type: string | Symbol, handler: Fn) { - const handlers = this.cache.get(type); - if (handlers) { - handlers.splice(handlers.indexOf(handler) >>> 0, 1); - } - } + /** + * 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(type: EventType, handler: Handler) { + const handlers = all?.get(type); + const added = handlers && handlers.push(handler); + if (!added) { + all?.set(type, [handler]); + } + }, - /** - * 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 {*} [evt] Any value (object is recommended and powerful), passed to each handler - */ - emit(type: string | Symbol, evt?: any) { - for (const handler of (this.cache.get(type) || []).slice()) handler(evt); - for (const handler of (this.cache.get('*') || []).slice()) handler(type, evt); - } + /** + * Remove an event handler for the given type. + * @param {string|symbol} type Type of event to unregister `handler` from, or `"*"` + * @param {Function} handler Handler function to remove + * @memberOf mitt + */ + off(type: EventType, handler: Handler) { + const handlers = all?.get(type); + if (handlers) { + handlers.splice(handlers.indexOf(handler) >>> 0, 1); + } + }, - /** - * Remove all event handlers. - * - * Note: This will also remove event handlers passed via `mitt(all: EventHandlerMap)`. - */ - clear() { - this.cache.clear(); - } + /** + * 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(type: EventType, evt: T) { + ((all?.get(type) || []) as EventHandlerList).slice().map((handler) => { + handler(evt); + }); + ((all?.get('*') || []) as WildCardEventHandlerList).slice().map((handler) => { + handler(type, evt); + }); + }, + }; } diff --git a/yarn.lock b/yarn.lock index bab66bd7202..3d26c8b9a36 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9760,10 +9760,10 @@ pretty-format@^27.0.2: ansi-styles "^5.0.0" react-is "^17.0.1" -pretty-quick@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.1.0.tgz#cb172e9086deb57455dea7c7e8f136cd0a4aef6c" - integrity sha512-DtxIxksaUWCgPFN7E1ZZk4+Aav3CCuRdhrDSFZENb404sYMtuo9Zka823F+Mgeyt8Zt3bUiCjFzzWYE9LYqkmQ== +pretty-quick@^3.1.1: + version "3.1.1" + resolved "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.1.1.tgz#93ca4e2dd38cc4e970e3f54a0ead317a25454688" + integrity sha512-ZYLGiMoV2jcaas3vTJrLvKAYsxDoXQBUn8OSTxkl67Fyov9lyXivJTl0+2WVh+y6EovGcw7Lm5ThYpH+Sh3XxQ== dependencies: chalk "^3.0.0" execa "^4.0.0" @@ -11765,10 +11765,10 @@ typescript-vscode-sh-plugin@^0.6.14: resolved "https://registry.npmjs.org/typescript-vscode-sh-plugin/-/typescript-vscode-sh-plugin-0.6.14.tgz#a81031b502f6346a26ea49ce082438c3e353bb38" integrity sha512-AkNlRBbI6K7gk29O92qthNSvc6jjmNQ6isVXoYxkFwPa8D04tIv2SOPd+sd+mNpso4tNdL2gy7nVtrd5yFqvlA== -typescript@4.3.3: - version "4.3.3" - resolved "https://registry.npmjs.org/typescript/-/typescript-4.3.3.tgz#5401db69bd3203daf1851a1a74d199cb3112c11a" - integrity sha512-rUvLW0WtF7PF2b9yenwWUi9Da9euvDRhmH7BLyBG4DCFfOJ850LGNknmRpp8Z8kXNUPObdZQEfKOiHtXuQHHKA== +typescript@4.3.4: + version "4.3.4" + resolved "https://registry.npmjs.org/typescript/-/typescript-4.3.4.tgz#3f85b986945bcf31071decdd96cf8bfa65f9dcbc" + integrity sha512-uauPG7XZn9F/mo+7MrsRjyvbxFpzemRjKEZXS4AK83oP2KKOJPvb+9cO/gmnv8arWZvhnjVOXz7B49m1l0e9Ew== uglify-js@^3.1.4: version "3.13.3"