diff --git a/miniprogram/core/EventEmitter.ts b/miniprogram/core/EventEmitter.ts new file mode 100644 index 0000000..2dc3cd7 --- /dev/null +++ b/miniprogram/core/EventEmitter.ts @@ -0,0 +1,119 @@ +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: keyof T, + event: T[keyof T] +) => 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< + keyof Events | '*', + EventHandlerList | WildCardEventHandlerList +>; + +export interface Emitter> { + all: EventHandlerMap; + + on(type: Key, handler: Handler): void; + on(type: '*', handler: WildcardHandler): void; + + off(type: Key, handler?: Handler): void; + off(type: '*', handler: WildcardHandler): void; + + emit(type: Key, event: Events[Key]): void; + emit(type: undefined extends Events[Key] ? Key : never): void; +} + +/** + * Mitt: Tiny (~200b) functional event emitter / pubsub. + * @name mitt + * @returns {Mitt} + */ +export default function mitt>( + all?: EventHandlerMap +): Emitter { + type GenericEventHandler = + | Handler + | WildcardHandler; + 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(type: Key, handler: GenericEventHandler) { + const handlers: Array | undefined = all!.get(type); + if (handlers) { + handlers.push(handler); + } + else { + all!.set(type, [handler] as EventHandlerList); + } + }, + + /** + * 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, or `'*'` + * @param {Function} [handler] Handler function to remove + * @memberOf mitt + */ + off(type: Key, handler?: GenericEventHandler) { + const handlers: Array | 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(type: Key, evt?: Events[Key]) { + let handlers = all!.get(type); + if (handlers) { + (handlers as EventHandlerList) + .slice() + .map((handler) => { + handler(evt!); + }); + } + + handlers = all!.get('*'); + if (handlers) { + (handlers as WildCardEventHandlerList) + .slice() + .map((handler) => { + handler(type, evt!); + }); + } + } + }; +} \ No newline at end of file diff --git a/miniprogram/core/Module.ts b/miniprogram/core/Module.ts index 9f84597..76ee33e 100644 --- a/miniprogram/core/Module.ts +++ b/miniprogram/core/Module.ts @@ -1,3 +1,4 @@ +import mitt, { Emitter, EventHandlerMap, EventType, Handler, WildcardHandler } from "./EventEmitter"; /** * 自定义对象类型 @@ -52,13 +53,15 @@ type Depends> = { * 页面模组 * @template M 所属 Manager * @template DEP 模组依赖 + * @template E 模组事件 * @template TD 模组 Data 类型 */ class Modular< M extends Manager = Manager, DEP extends Depends = Depends, + E extends Record = Record, TD extends IAnyTypeObject = IAnyTypeObject> -implements WXContext { +implements WXContext, Emitter { // [x:string]: any; @@ -125,6 +128,34 @@ implements WXContext { this.functionList = new Set(); this.paramList = new Set(); this.nameSpace = nameSpace; + + this.emitter = mitt(); + + } + + /** + * 内部事件控制器 + */ + private emitter:Emitter; + + public get all():EventHandlerMap { return this.emitter.all }; + + on(type: Key, handler: Handler): void; + on(type: "*", handler: WildcardHandler): void; + on(type: any, handler: any): void { + return this.emitter.on(type, handler); + } + + off(type: Key, handler?: Handler): void; + off(type: "*", handler: WildcardHandler): void; + off(type: any, handler?: any): void { + return this.emitter.off(type, handler); + } + + emit(type: Key, event: E[Key]): void; + emit(type: undefined extends E[Key] ? Key : never): void; + emit(type: any, event?: any): void { + return this.emitter.emit(type, event); } public setData(data:Partial, callback?: () => void):void { @@ -301,8 +332,10 @@ class Manager { for(let i = 0; i < this.modules.length; i++) { - let res: Promise | any = - (this.modules[i] as IAnyTypeObject)[key](...arg); + let fn:Function = (this.modules[i] as IAnyTypeObject)[key]; + + if(fn === void 0) continue; + let res: Promise | any = fn.apply(this.modules[i], arg); if (res instanceof Promise) { hooks.push(res); diff --git a/miniprogram/pages/Timetable/Timetable.ts b/miniprogram/pages/Timetable/Timetable.ts index 0cc3a60..163721c 100644 --- a/miniprogram/pages/Timetable/Timetable.ts +++ b/miniprogram/pages/Timetable/Timetable.ts @@ -7,7 +7,7 @@ Page({ /** * 课程表页面加载 */ - onLoad: async function () { + onLoad: async function (query) { this; @@ -15,8 +15,7 @@ Page({ let m1 = manager.addModule(M1, "m1"); let m2 = manager.addModule(M2, "m2", {m1}); - let manager2 = new Manager(this); - let m22 = manager.addModule(M2, "m1", {m1}); + manager.loadAllModule(query); this.setData; @@ -48,21 +47,25 @@ Page({ }) -class M1 extends Modular { +class M1 extends Modular implements Partial { public onLoad(){ } + + public onReady() { + console.log(this); + this.emit("lll", {a:1}) + } } class M2 extends Modular}> { public onLoad() { - // this.setData(); + this.setData({a:1}); + this.depends?.m1.on("lll", (e)=>{ + console.log(e) + }) + console.log(this); } - // hhh(){ - - // } - - hh(){} } \ No newline at end of file