本事件封裝類特色是支持對象事件名,支持弱應用,可以確保監聽自動刪除
// 用 Symbol模擬私有變量
const event = Symbol("eventPropery");
const eventWeak = Symbol("eventProperyWeak");
const getEvent = Symbol("getEvent");
const isWeakEvent = Symbol("isWeakEvent");
/**
* 一個公共的事件處理器 用於誇組件通信
*/
class EventSelf {
constructor() {
this[event] = {};
this[eventWeak] = new WeakMap();
}
[isWeakEvent](eventName) {
return eventName !== null && typeof eventName === "object";
}
[getEvent](eventName) {
let funs = null;
if (this[isWeakEvent](eventName)) {
funs = this[eventWeak].get(eventName);
} else {
funs = this[event][eventName];
}
return funs;
}
/**
* 監聽事件
* @param {*} eventName 任意值
* @param {*} fun 必須是一個函數
* @returns 返回一個解除事件監聽函數
*/
on(eventName, fun) {
let voidFun = () => {};
if (!fun || !(fun instanceof Function)) {
return voidFun;
}
if (!eventName) {
return voidFun;
}
const funs = this[getEvent](eventName);
if (!funs) {
if (this[isWeakEvent](eventName)) {
this[eventWeak].set(eventName, [fun]);
} else {
this[event][eventName] = [fun];
}
} else {
funs.push(fun);
}
return () => {
this.unBind(eventName, fun);
};
}
/**
* 觸發事件
* @param {*} eventName 任意值
* @param {*} val 任意值
* @returns
*/
emit(eventName, val) {
if (!eventName) {
return;
}
const funs = this[getEvent](eventName);
if (!funs || funs.length === 0) {
return;
}
for (const fun of funs) {
if (fun && fun instanceof Function) {
fun(val);
}
}
}
/**
* 解除事件監聽
* @param {*} eventName 任意值
* @param {*} fun 必須是函數
* @returns
*/
unBind(eventName, fun) {
const funs = this[getEvent](eventName);
if (!funs || funs.length === 0) {
return;
}
if (!(fun instanceof Function)) {
return;
}
console.log('解綁函數開始執行',eventName,funs)
const index = funs.findIndex((item) => item === fun);
if (index !== -1) {
funs.splice(index, 1);
}
console.log('解綁函數被執行',eventName,funs)
}
}
export const gEventName = { login: "login" };
export const gEvent = new EventSelf();