Преглед на файлове

实现SysStorage/EventBus

Renxy преди 2 години
родител
ревизия
2c1fae7057

+ 15 - 0
src/Engine/EventBus/EventBus.ts

@@ -0,0 +1,15 @@
+import { MessageType } from '@/Frameworks/MessageType';
+import { useEffect } from 'react';
+import EventAction, { EventHandler } from '.';
+const EventBus = new EventAction();
+export { EventBus };
+
+export const useEventBus = <T = any>(
+  type: MessageType,
+  cb: EventHandler<T>,
+) => {
+  useEffect(() => {
+    EventBus.on(type, cb);
+    return () => EventBus.off(type, cb);
+  });
+};

+ 61 - 0
src/Engine/EventBus/index.ts

@@ -0,0 +1,61 @@
+import { MessageType } from '@/Frameworks/MessageType';
+
+export type EventHandler<E = any> = (e: E) => void;
+// export interface EventType {
+//   [type: MessageType]: EventHandler<E>[];
+// }
+class EventAction<E = any> {
+  private _events: { [type in MessageType]?: EventHandler<E>[] }; //Record<MessageType, EventHandler<E>[]>;
+  constructor() {
+    this._events = {};
+  }
+
+  private _getFns(type: MessageType) {
+    return this._events[type] || (this._events[type] = []);
+  }
+
+  public on(type: MessageType, cb: EventHandler<E>): void {
+    const fus = this._getFns(type);
+    fus.push(cb);
+  }
+
+  public off(type: MessageType, cb?: EventHandler<E>): void {
+    if (cb) {
+      const fus = this._getFns(type);
+      const index = fus.indexOf(cb);
+      if (index != -1) {
+        fus.splice(index, 1);
+      }
+    } else {
+      delete this._events[type];
+    }
+  }
+
+  public once(type: MessageType, cb: EventHandler<E>): void {
+    const fn2: EventHandler<E> = (e) => {
+      this.off(type, fn2);
+      cb(e as any);
+    };
+    this.on(type, fn2);
+  }
+
+  //同步调用
+  public emit(type: MessageType, params?: E): void {
+    const fns = this._getFns(type);
+    fns.forEach((item) => item(params as any));
+  }
+  /* 可以异步调用,返回一个Promise */
+  public invoke(event: MessageType, param?: E): Promise<any> {
+    const fns = this._getFns(event);
+
+    for (let i = 0; i < fns.length; i++) {
+      const fn = fns[i];
+      return new Promise<any>((resolve, reject) => {
+        resolve(fn(param as any));
+      });
+    }
+    return Promise.reject();
+  }
+}
+
+export default EventAction;

+ 39 - 0
src/Engine/Storage/index.ts

@@ -0,0 +1,39 @@
+import { SysStorage } from '@/Frameworks/SysStorage';
+
+const useStorage = (storage: Storage) => {
+  const setItem = <T>(key: SysStorage, value: T) => {
+    storage.setItem(key, value ? JSON.stringify(value) : '');
+  };
+
+  const getItem = (key: SysStorage) => {
+    let value: string = storage.getItem(key) || '';
+    try {
+      value = JSON.parse(value);
+      return value;
+    } catch {
+      return value;
+    }
+  };
+
+  const removeItem = (key: SysStorage) => {
+    storage.removeItem(key);
+  };
+
+  const clearAll = () => {
+    for (const key in storage) {
+      if (key) {
+        storage.removeItem(key);
+      }
+    }
+  };
+  return {
+    setItem,
+    getItem,
+    removeItem,
+    clearAll,
+  };
+};
+const SessionService = useStorage(window.sessionStorage || sessionStorage);
+const LocalService = useStorage(window.localStorage || sessionStorage);
+
+export { SessionService, LocalService };

+ 3 - 5
src/Frameworks/MessageType.ts

@@ -1,9 +1,7 @@
-enum MessageType {
+export enum MessageType {
   dataMeter = 1,
   a,
   b = 100,
-  c
+  c,
 }
-
-
-export {}
+// export {}

+ 4 - 2
src/Frameworks/SysStorage.ts

@@ -1,2 +1,4 @@
-
-export {}
+export enum SysStorage {
+  token = 'token',
+}
+// export {}

+ 47 - 1
src/Project/pages/Access/index.tsx

@@ -1,11 +1,37 @@
+import { EventBus, useEventBus } from '@/Engine/EventBus/EventBus';
+import { LocalService, SessionService } from '@/Engine/Storage';
+import { MessageType } from '@/Frameworks/MessageType';
+import { SysStorage } from '@/Frameworks/SysStorage';
 import { FuncMainState } from '@/Project/Functions/FuncMain';
 import { PageContainer } from '@ant-design/pro-components';
 import { Access, useAccess } from '@umijs/max';
 import { Button } from 'antd';
+import { useState } from 'react';
 
 const AccessPage: React.FC<GT.IPageProps> = (props) => {
   const access = useAccess();
   console.log(props);
+
+  const ComponentA = () => {
+    return (
+      <Button
+        onClick={() => {
+          EventBus.emit(MessageType.a, 'hahahah');
+        }}
+      >
+        向B传递参数
+      </Button>
+    );
+  };
+  const ComponentB = () => {
+    const [text, setText] = useState('');
+    const func = (text: string) => {
+      setText(text);
+    };
+    useEventBus(MessageType.a, func);
+    return <Button>参数为:{text}</Button>;
+  };
+
   return (
     <PageContainer
       ghost
@@ -17,7 +43,27 @@ const AccessPage: React.FC<GT.IPageProps> = (props) => {
         <Button>只有 Admin 可以看到这个按钮</Button>
       </Access> */}
       ACCESS Page
-      <Button onClick={() => window.GT_APP.FuncMain.changeState(FuncMainState.Login)}>push</Button>
+      <Button
+        onClick={() => window.GT_APP.funcMain.changeState(FuncMainState.Login)}
+      >
+        push
+      </Button>
+      <Button
+        onClick={() => {
+          SessionService.setItem(SysStorage.token, 'token11111');
+        }}
+      >
+        存Session地址
+      </Button>
+      <Button
+        onClick={() => {
+          LocalService.setItem(SysStorage.token, 'token11111');
+        }}
+      >
+        存Local地址
+      </Button>
+      <ComponentA />
+      <ComponentB />
     </PageContainer>
   );
 };

+ 1 - 1
src/Project/pages/Home/index.tsx

@@ -11,7 +11,7 @@ const HomePage: React.FC = () => {
       <div
         className={styles.container}
         onClick={() => {
-          window.GT_APP.FuncMain.changeState(FuncMainState.ProjectSelection);
+          window.GT_APP.funcMain.changeState(FuncMainState.ProjectSelection);
         }}
       >
         HOME