@heathenjs/taro-router 1.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/README.md +46 -0
  2. package/dist/back-listener/index.d.ts +7 -0
  3. package/dist/back-listener/index.js +21 -0
  4. package/dist/back-listener/index.js.map +1 -0
  5. package/dist/back-listener/type.d.ts +2 -0
  6. package/dist/back-listener/type.js +3 -0
  7. package/dist/back-listener/type.js.map +1 -0
  8. package/dist/constants.d.ts +1 -0
  9. package/dist/constants.js +5 -0
  10. package/dist/constants.js.map +1 -0
  11. package/dist/core/index.d.ts +41 -0
  12. package/dist/core/index.js +213 -0
  13. package/dist/core/index.js.map +1 -0
  14. package/dist/core/type.d.ts +28 -0
  15. package/dist/core/type.js +15 -0
  16. package/dist/core/type.js.map +1 -0
  17. package/dist/exception/index.d.ts +1 -0
  18. package/dist/exception/index.js +6 -0
  19. package/dist/exception/index.js.map +1 -0
  20. package/dist/exception/no-page.d.ts +3 -0
  21. package/dist/exception/no-page.js +10 -0
  22. package/dist/exception/no-page.js.map +1 -0
  23. package/dist/index.d.ts +9 -0
  24. package/dist/index.js +18 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/middleware/index.d.ts +10 -0
  27. package/dist/middleware/index.js +50 -0
  28. package/dist/middleware/index.js.map +1 -0
  29. package/dist/middleware/type.d.ts +13 -0
  30. package/dist/middleware/type.js +3 -0
  31. package/dist/middleware/type.js.map +1 -0
  32. package/dist/page-data/index.d.ts +15 -0
  33. package/dist/page-data/index.js +52 -0
  34. package/dist/page-data/index.js.map +1 -0
  35. package/dist/utils/compose.d.ts +9 -0
  36. package/dist/utils/compose.js +46 -0
  37. package/dist/utils/compose.js.map +1 -0
  38. package/dist/utils/get-current-route-key.d.ts +1 -0
  39. package/dist/utils/get-current-route-key.js +16 -0
  40. package/dist/utils/get-current-route-key.js.map +1 -0
  41. package/dist/utils/index.d.ts +3 -0
  42. package/dist/utils/index.js +20 -0
  43. package/dist/utils/index.js.map +1 -0
  44. package/dist/utils/is-nil.d.ts +1 -0
  45. package/dist/utils/is-nil.js +7 -0
  46. package/dist/utils/is-nil.js.map +1 -0
  47. package/dist/utils/merge-props.d.ts +3 -0
  48. package/dist/utils/merge-props.js +16 -0
  49. package/dist/utils/merge-props.js.map +1 -0
  50. package/package.json +37 -0
  51. package/src/back-listener/index.ts +21 -0
  52. package/src/back-listener/type.ts +3 -0
  53. package/src/constants.ts +1 -0
  54. package/src/core/index.ts +189 -0
  55. package/src/core/type.ts +30 -0
  56. package/src/exception/index.ts +1 -0
  57. package/src/exception/no-page.ts +5 -0
  58. package/src/index.ts +12 -0
  59. package/src/middleware/index.ts +40 -0
  60. package/src/middleware/type.ts +16 -0
  61. package/src/page-data/index.ts +67 -0
  62. package/src/utils/compose.ts +37 -0
  63. package/src/utils/get-current-route-key.ts +10 -0
  64. package/src/utils/index.ts +3 -0
  65. package/src/utils/is-nil.ts +3 -0
  66. package/src/utils/merge-props.ts +16 -0
  67. package/tsconfig.json +25 -0
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PageData = void 0;
4
+ const utils_1 = require("../utils");
5
+ class PageData {
6
+ static getPageData(default_value) {
7
+ const route_key = (0, utils_1.getCurrentRouteKey)();
8
+ const result = PageData.pageData.get(route_key) || default_value;
9
+ return result;
10
+ }
11
+ static delPageData(route_key) {
12
+ PageData.pageData.delete(route_key);
13
+ }
14
+ static delPagePromise(route_key) {
15
+ PageData.pagePromise.delete(route_key);
16
+ }
17
+ static setPageData(route_key, data) {
18
+ this.pageData.set(route_key, data);
19
+ }
20
+ static setPagePromise(route_key, options) {
21
+ this.pagePromise.set(route_key, options);
22
+ }
23
+ static emitBack(route_key) {
24
+ const pme = PageData.pagePromise.get(route_key);
25
+ if (!pme)
26
+ return;
27
+ const result = PageData.backResult.get(route_key);
28
+ PageData.delPageData(route_key);
29
+ PageData.delPagePromise(route_key);
30
+ if (result) {
31
+ PageData.backResult.delete(route_key);
32
+ if (result instanceof Error) {
33
+ pme.rej(result);
34
+ }
35
+ else {
36
+ pme.res(result);
37
+ }
38
+ }
39
+ else {
40
+ pme.res(null);
41
+ }
42
+ }
43
+ static setBackResult(result) {
44
+ const route_key = (0, utils_1.getCurrentRouteKey)();
45
+ PageData.backResult.set(route_key, result);
46
+ }
47
+ }
48
+ exports.PageData = PageData;
49
+ PageData.pageData = new Map();
50
+ PageData.pagePromise = new Map();
51
+ PageData.backResult = new Map();
52
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/page-data/index.ts"],"names":[],"mappings":";;;AAAA,oCAA8C;AAE9C,MAAa,QAAQ;IAYnB,MAAM,CAAC,WAAW,CAAU,aAAiB;QAC3C,MAAM,SAAS,GAAG,IAAA,0BAAkB,GAAE,CAAC;QACvC,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,aAAa,CAAC;QACjE,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,MAAM,CAAC,WAAW,CAAC,SAAiB;QAC1C,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC;IAEO,MAAM,CAAC,cAAc,CAAC,SAAiB;QAC7C,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACzC,CAAC;IAED,MAAM,CAAC,WAAW,CAAC,SAAiB,EAAE,IAAS;QAC7C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACrC,CAAC;IAED,MAAM,CAAC,cAAc,CACnB,SAAiB,EACjB,OAGC;QAED,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,CAAC,QAAQ,CAAC,SAAiB;QAC/B,MAAM,GAAG,GAAG,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAChD,IAAI,CAAC,GAAG;YAAE,OAAO;QACjB,MAAM,MAAM,GAAG,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAElD,QAAQ,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QAChC,QAAQ,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;QAEnC,IAAI,MAAM,EAAE,CAAC;YACX,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YACtC,IAAI,MAAM,YAAY,KAAK,EAAE,CAAC;gBAC5B,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAClB,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC;IACH,CAAC;IAED,MAAM,CAAC,aAAa,CAAC,MAAW;QAC9B,MAAM,SAAS,GAAG,IAAA,0BAAkB,GAAE,CAAC;QACvC,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC7C,CAAC;;AA/DH,4BAgEC;AA/DgB,iBAAQ,GAAqB,IAAI,GAAG,EAAE,CAAC;AACvC,oBAAW,GAMtB,IAAI,GAAG,EAAE,CAAC;AAEC,mBAAU,GAAqB,IAAI,GAAG,EAAE,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Compose `middleware` returning
3
+ * a fully valid middleware comprised
4
+ * of all those which are passed.
5
+ *
6
+ * @param {Array} middleware
7
+ * @return {Function}
8
+ */
9
+ export declare function compose(middleware: Function[]): (context: any, next?: Function) => Promise<any>;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.compose = compose;
4
+ /**
5
+ * Compose `middleware` returning
6
+ * a fully valid middleware comprised
7
+ * of all those which are passed.
8
+ *
9
+ * @param {Array} middleware
10
+ * @return {Function}
11
+ */
12
+ function compose(middleware) {
13
+ if (!Array.isArray(middleware))
14
+ throw new TypeError('Middleware stack must be an array!');
15
+ for (const fn of middleware) {
16
+ if (typeof fn !== 'function')
17
+ throw new TypeError('Middleware must be composed of functions!');
18
+ }
19
+ /**
20
+ * @param {Object} context
21
+ * @return {Promise}
22
+ * @api public
23
+ */
24
+ return function (context, next) {
25
+ // last called middleware #
26
+ let index = -1;
27
+ const dispatch = (i) => {
28
+ if (i <= index)
29
+ return Promise.reject(new Error('next() called multiple times'));
30
+ index = i;
31
+ let fn = middleware[i];
32
+ if (i === middleware.length)
33
+ fn = next;
34
+ if (!fn)
35
+ return Promise.resolve();
36
+ try {
37
+ return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));
38
+ }
39
+ catch (err) {
40
+ return Promise.reject(err);
41
+ }
42
+ };
43
+ return dispatch(0);
44
+ };
45
+ }
46
+ //# sourceMappingURL=compose.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compose.js","sourceRoot":"","sources":["../../src/utils/compose.ts"],"names":[],"mappings":";;AAQA,0BA4BC;AApCD;;;;;;;GAOG;AACH,SAAgB,OAAO,CAAC,UAAsB;IAC5C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC;QAAE,MAAM,IAAI,SAAS,CAAC,oCAAoC,CAAC,CAAC;IAC1F,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;QAC5B,IAAI,OAAO,EAAE,KAAK,UAAU;YAAE,MAAM,IAAI,SAAS,CAAC,2CAA2C,CAAC,CAAC;IACjG,CAAC;IAED;;;;OAIG;IACH,OAAO,UAAU,OAAY,EAAE,IAAe;QAC5C,2BAA2B;QAC3B,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC;QACf,MAAM,QAAQ,GAAG,CAAC,CAAS,EAAgB,EAAE;YAC3C,IAAI,CAAC,IAAI,KAAK;gBAAE,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC,CAAC;YACjF,KAAK,GAAG,CAAC,CAAC;YACV,IAAI,EAAE,GAAyB,UAAU,CAAC,CAAC,CAAC,CAAC;YAC7C,IAAI,CAAC,KAAK,UAAU,CAAC,MAAM;gBAAE,EAAE,GAAG,IAAI,CAAC;YACvC,IAAI,CAAC,EAAE;gBAAE,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;YAClC,IAAI,CAAC;gBACH,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAClE,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC,CAAC;QACF,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC;IACrB,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function getCurrentRouteKey(): string;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getCurrentRouteKey = getCurrentRouteKey;
7
+ const taro_1 = __importDefault(require("@tarojs/taro"));
8
+ const constants_1 = require("../constants");
9
+ function getCurrentRouteKey() {
10
+ if (!taro_1.default.Current.page) {
11
+ return '';
12
+ }
13
+ // TODO: taro官方缺少类型定义,as any过渡一下
14
+ return taro_1.default.Current.page[constants_1.ROUTE_KEY];
15
+ }
16
+ //# sourceMappingURL=get-current-route-key.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-current-route-key.js","sourceRoot":"","sources":["../../src/utils/get-current-route-key.ts"],"names":[],"mappings":";;;;;AAGA,gDAMC;AATD,wDAAgC;AAChC,4CAAyC;AAEzC,SAAgB,kBAAkB;IAChC,IAAI,CAAC,cAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QACvB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,gCAAgC;IAChC,OAAQ,cAAI,CAAC,OAAO,CAAC,IAAY,CAAC,qBAAS,CAAC,CAAC;AAC/C,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './get-current-route-key';
2
+ export * from './is-nil';
3
+ export * from './merge-props';
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./get-current-route-key"), exports);
18
+ __exportStar(require("./is-nil"), exports);
19
+ __exportStar(require("./merge-props"), exports);
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0DAAwC;AACxC,2CAAyB;AACzB,gDAA8B"}
@@ -0,0 +1 @@
1
+ export declare function isNil(val: any): boolean;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isNil = isNil;
4
+ function isNil(val) {
5
+ return val === undefined || val === null;
6
+ }
7
+ //# sourceMappingURL=is-nil.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"is-nil.js","sourceRoot":"","sources":["../../src/utils/is-nil.ts"],"names":[],"mappings":";;AAAA,sBAEC;AAFD,SAAgB,KAAK,CAAC,GAAQ;IAC5B,OAAO,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,IAAI,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,3 @@
1
+ type MergeResult<T extends any[]> = T extends [infer First, ...infer Rest] ? First & MergeResult<Rest> : {};
2
+ export declare function mergeProps<T extends object[]>(...items: [...T]): MergeResult<T>;
3
+ export {};
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.mergeProps = mergeProps;
4
+ function mergeProps(...items) {
5
+ const result = {};
6
+ for (const item of items) {
7
+ for (const key in item) {
8
+ const value = item[key];
9
+ if (value !== undefined) {
10
+ result[key] = value;
11
+ }
12
+ }
13
+ }
14
+ return result;
15
+ }
16
+ //# sourceMappingURL=merge-props.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge-props.js","sourceRoot":"","sources":["../../src/utils/merge-props.ts"],"names":[],"mappings":";;AAEA,gCAaC;AAbD,SAAgB,UAAU,CAAqB,GAAG,KAAa;IAC7D,MAAM,MAAM,GAAQ,EAAE,CAAC;IAEvB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,KAAK,GAAI,IAAY,CAAC,GAAG,CAAC,CAAC;YACjC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YACtB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAwB,CAAC;AAClC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@heathenjs/taro-router",
3
+ "version": "1.1.5",
4
+ "description": "Taro小程序路由库",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "files": [
8
+ "dist",
9
+ "src",
10
+ "package.json",
11
+ "tsconfig.json",
12
+ "README.md"
13
+ ],
14
+ "keywords": [
15
+ "taro",
16
+ "router",
17
+ "react",
18
+ "miniprogram"
19
+ ],
20
+ "publishConfig": {
21
+ "access": "public",
22
+ "registry": "https://registry.npmjs.org/"
23
+ },
24
+ "author": "heathen1998",
25
+ "license": "MIT",
26
+ "peerDependencies": {
27
+ "@tarojs/taro": "^3.6.35",
28
+ "react": "^18.0.0"
29
+ },
30
+ "scripts": {
31
+ "prod": "tsc -p ./tsconfig.json",
32
+ "clean": "rimraf dist",
33
+ "build": "pnpm run clean && pnpm run prod",
34
+ "tsc": "tsc -p ./tsconfig.json --noEmit",
35
+ "lint": "eslint --ext .ts --max-warnings 0 \"./src\" "
36
+ }
37
+ }
@@ -0,0 +1,21 @@
1
+ import { Current } from '@tarojs/taro';
2
+ import { Route } from '../core';
3
+ import { RouterBackListener } from './type';
4
+
5
+ export type { RouterBackListener };
6
+
7
+ export const routerBackListenerCollection: RouterBackListener[] = [];
8
+
9
+ /** 注册全局路由返回监听 */
10
+ export function registerRouterBackListener(listener: RouterBackListener) {
11
+ routerBackListenerCollection.push(listener);
12
+ }
13
+
14
+ export function execRouterBackListener(from: Route) {
15
+ const to = {
16
+ url: Current.router?.path || '',
17
+ };
18
+ for (const listener of routerBackListenerCollection) {
19
+ listener(to, from);
20
+ }
21
+ }
@@ -0,0 +1,3 @@
1
+ import { Route } from '../core';
2
+
3
+ export type RouterBackListener = (to: Route, from: Route) => any;
@@ -0,0 +1 @@
1
+ export const ROUTE_KEY = 'route_key';
@@ -0,0 +1,189 @@
1
+ import Taro, { Current, getCurrentInstance } from '@tarojs/taro';
2
+ import { useRef } from 'react';
3
+ import { ROUTE_KEY } from '../constants';
4
+ import { NoPageException } from '../exception/no-page';
5
+ import { execMiddlewares, getMiddlewares, RouteContext } from '../middleware';
6
+ import { PageData } from '../page-data';
7
+ import { execRouterBackListener } from '../back-listener';
8
+ import { getCurrentRouteKey, isNil, mergeProps } from '../utils';
9
+ import { NavigateOptions, NavigateType, Route } from './type';
10
+
11
+ export { NavigateType } from './type';
12
+ export type { NavigateOptions, Route } from './type';
13
+
14
+ type RouterInitConfig = {
15
+ defaultExt: Record<any, any>;
16
+ };
17
+
18
+ export class Router {
19
+ private static defaultExt: object;
20
+
21
+ static init(initConfig: RouterInitConfig) {
22
+ this.defaultExt = initConfig.defaultExt;
23
+ }
24
+
25
+ /**
26
+ * 页面跳转
27
+ * @param route 目标路由对象
28
+ * @param options 跳转选项
29
+ */
30
+ static async navigate<T = any>(route: Route, options?: NavigateOptions): Promise<T> {
31
+ options = { ...{ type: NavigateType.navigateTo, params: {} }, ...options };
32
+ options.params = Object.assign({}, options.params);
33
+ const route_key = Date.now() + '';
34
+
35
+ // TODO: taro官方缺少类型定义,as any过渡一下
36
+ (Current as any)['_page'] = Current.page;
37
+ Object.defineProperties(Current, {
38
+ page: {
39
+ set: function (page) {
40
+ if (page === undefined || page === null) {
41
+ this._page = page;
42
+ return;
43
+ }
44
+ if (!page[ROUTE_KEY]) {
45
+ const originOnUnload = page.onUnload;
46
+ page.onUnload = function () {
47
+ originOnUnload && originOnUnload.apply(this);
48
+ PageData.emitBack(route_key);
49
+ setTimeout(() => execRouterBackListener(route));
50
+ };
51
+ page[ROUTE_KEY] = route_key;
52
+ }
53
+ this._page = page;
54
+ },
55
+ get: function () {
56
+ return this._page;
57
+ },
58
+ },
59
+ });
60
+
61
+ if (options.params) {
62
+ PageData.setPageData(route_key, options.params);
63
+ }
64
+
65
+ const pathToPagePackageName = (Router?.['_pathToPagePackageNameObj'] ?? []) as Record<string, string>;
66
+
67
+ const context: RouteContext = {
68
+ route: {
69
+ url: route.url,
70
+ ext: mergeProps(this.defaultExt, route.ext),
71
+ },
72
+ type: options.type!,
73
+ params: options.params,
74
+ packageName: pathToPagePackageName[route.url],
75
+ };
76
+
77
+ const middlewares = getMiddlewares(context);
78
+ middlewares.push(async (_, next) => {
79
+ switch (options!.type) {
80
+ case NavigateType.reLaunch:
81
+ await Taro.reLaunch({
82
+ url: route.url,
83
+ complete: options?.complete,
84
+ fail: options?.fail,
85
+ success: options?.success,
86
+ });
87
+ break;
88
+ case NavigateType.redirectTo:
89
+ await Taro.redirectTo({
90
+ url: route.url,
91
+ complete: options?.complete,
92
+ fail: options?.fail,
93
+ success: options?.success,
94
+ });
95
+ break;
96
+ case NavigateType.switchTab:
97
+ await Taro.switchTab({
98
+ url: route.url,
99
+ complete: options?.complete,
100
+ fail: options?.fail,
101
+ success: options?.success,
102
+ });
103
+ break;
104
+ default:
105
+ await Taro.navigateTo({
106
+ url: route.url,
107
+ complete: options?.complete,
108
+ fail: options?.fail,
109
+ success: options?.success,
110
+ });
111
+ break;
112
+ }
113
+ next();
114
+ });
115
+
116
+ return new Promise(async (res, rej) => {
117
+ try {
118
+ PageData.setPagePromise(route_key, { res, rej });
119
+ await execMiddlewares(middlewares, context);
120
+ } catch (err) {
121
+ rej(err);
122
+ }
123
+ });
124
+ }
125
+
126
+ /**
127
+ * 返回上一个页面
128
+ * @param result 返回给上一个页面的数据,如果 result 是 Error 的实例,则是抛出异常给上一个页面
129
+ * @param options 其他选项
130
+ */
131
+ static back(
132
+ result?: unknown,
133
+ options?: {
134
+ /** 返回的页面数,如果 delta 大于现有页面数,则返回到首页。 */
135
+ delta?: number;
136
+ },
137
+ ) {
138
+ if (!isNil(result)) {
139
+ PageData.setBackResult(result);
140
+ }
141
+
142
+ const currentPages = Taro.getCurrentPages();
143
+ if (currentPages.length > 1) {
144
+ return Taro.navigateBack(options);
145
+ }
146
+
147
+ throw new NoPageException();
148
+ }
149
+
150
+ /**
151
+ * 设置页面返回的数据
152
+ * 当物理键返回和左上角返回也需要带数据时会使用到
153
+ */
154
+ static setBackResult(result: any) {
155
+ PageData.setBackResult(result);
156
+ }
157
+
158
+ /**
159
+ * 获取页面携带过来的数据,混合顺序为 路由参数 > URL参数
160
+ * @param default_value 默认参数
161
+ */
162
+ static getParams<T extends Record<string, any> = {}>(): T {
163
+ const urlParams = Object.assign({}, getCurrentInstance().router?.params) as T;
164
+ const routerParams = PageData.getPageData<T>();
165
+ return mergeProps(urlParams, routerParams);
166
+ }
167
+
168
+ /**
169
+ * 获取页面携带过来的数据,混合顺序为 路由参数 > URL参数
170
+ * @param default_value 默认参数
171
+ */
172
+ static useParams<T extends Record<string, any> = {}>(): T {
173
+ // eslint-disable-next-line react-hooks/rules-of-hooks
174
+ const { current } = useRef({
175
+ obj: {} as T,
176
+ initialized: false,
177
+ });
178
+ if (current.initialized === false) {
179
+ current.obj = this.getParams();
180
+ current.initialized = true;
181
+ }
182
+ return current.obj;
183
+ }
184
+
185
+ static setParams<T extends Record<string, any> = {}>(value: T) {
186
+ const route_key = getCurrentRouteKey();
187
+ PageData.setPageData(route_key, value);
188
+ }
189
+ }
@@ -0,0 +1,30 @@
1
+ export interface Route<E = any> {
2
+ /** 页面 url,与配置在 app.config.ts 中的一致 */
3
+ url: string;
4
+ /** 附加数据 */
5
+ ext?: E;
6
+ }
7
+
8
+ export enum NavigateType {
9
+ /** 保留当前页面,跳转到应用内的某个页面。但是不能跳到 tabbar 页面。使用 Router.back 可以返回到原页面。小程序中页面栈最多十层。 */
10
+ navigateTo = 'navigateTo',
11
+ /** 关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到 tabbar 页面。 */
12
+ redirectTo = 'redirectTo',
13
+ /** 关闭所有页面,打开到应用内的某个页面 */
14
+ reLaunch = 'reLaunch',
15
+ /** 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面 */
16
+ switchTab = 'switchTab',
17
+ }
18
+
19
+ export interface NavigateOptions {
20
+ /** 跳转类型 */
21
+ type?: NavigateType;
22
+ /** 路由参数 */
23
+ params?: unknown;
24
+ /** 跳转完成的回调方法 */
25
+ complete?: (res: TaroGeneral.CallbackResult) => void;
26
+ /** 跳转失败的回调方法 */
27
+ fail?: (res: TaroGeneral.CallbackResult) => void;
28
+ /** 跳转成功的回调方法 */
29
+ success?: (res: TaroGeneral.CallbackResult) => void;
30
+ }
@@ -0,0 +1 @@
1
+ export { NoPageException } from './no-page';
@@ -0,0 +1,5 @@
1
+ export class NoPageException extends Error {
2
+ constructor() {
3
+ super('没有页面可以返回');
4
+ }
5
+ }
package/src/index.ts ADDED
@@ -0,0 +1,12 @@
1
+ import { Router } from './core';
2
+
3
+ export { NoPageException } from './exception';
4
+ export { execMiddlewares, getMiddlewares, registerMiddleware, registerMiddlewares } from './middleware';
5
+ export { NavigateType, Router } from './core';
6
+ export { registerRouterBackListener } from './back-listener';
7
+
8
+ export type { Middleware, MiddlewareCondition, RouteContext } from './middleware';
9
+ export type { NavigateOptions, Route } from './core';
10
+ export type { RouterBackListener } from './back-listener';
11
+
12
+ export default Router;
@@ -0,0 +1,40 @@
1
+ import { compose } from '../utils/compose';
2
+ import { Middleware, MiddlewareCondition, RouteContext } from './type';
3
+
4
+ export type { Middleware, MiddlewareCondition, RouteContext };
5
+
6
+ export const middlewareCollection: {
7
+ middlewares: Middleware[];
8
+ condition?: MiddlewareCondition;
9
+ }[] = [];
10
+
11
+ export function registerMiddleware(middleware: Middleware, condition?: MiddlewareCondition) {
12
+ middlewareCollection.push({
13
+ middlewares: [middleware],
14
+ condition,
15
+ });
16
+ }
17
+
18
+ export function registerMiddlewares(middlewares: Middleware[], condition?: MiddlewareCondition) {
19
+ middlewareCollection.push({
20
+ middlewares,
21
+ condition,
22
+ });
23
+ }
24
+
25
+ export function getMiddlewares(ctx: RouteContext) {
26
+ return middlewareCollection
27
+ .filter((mc) => {
28
+ if (!mc.condition) return true;
29
+ else return mc.condition(ctx);
30
+ })
31
+ .map((mc) => mc.middlewares)
32
+ .reduce((pre, cur) => {
33
+ return [...pre, ...cur];
34
+ }, []);
35
+ }
36
+
37
+ export async function execMiddlewares(middlewares: Middleware[], ctx: RouteContext) {
38
+ const fn = compose(middlewares);
39
+ return await fn(ctx);
40
+ }
@@ -0,0 +1,16 @@
1
+ import { NavigateType, Route } from '../core/type';
2
+
3
+ export interface RouteContext<E = any> {
4
+ /** 目标路由 */
5
+ route: Route<E>;
6
+ /** 路由参数 */
7
+ params: any;
8
+ /** 跳转类型 */
9
+ type: NavigateType;
10
+ /** 路由所在包 */
11
+ packageName?: string;
12
+ }
13
+
14
+ export type Middleware<E = any> = (ctx: RouteContext<E>, next: () => Promise<any>) => Promise<void>;
15
+
16
+ export type MiddlewareCondition = (ctx: RouteContext) => boolean;
@@ -0,0 +1,67 @@
1
+ import { getCurrentRouteKey } from '../utils';
2
+
3
+ export class PageData {
4
+ private static pageData: Map<string, any> = new Map();
5
+ private static pagePromise: Map<
6
+ string,
7
+ {
8
+ res: (val: any) => void;
9
+ rej: (err: any) => void;
10
+ }
11
+ > = new Map();
12
+
13
+ private static backResult: Map<string, any> = new Map();
14
+
15
+ static getPageData<T = any>(default_value?: T): T {
16
+ const route_key = getCurrentRouteKey();
17
+ const result = PageData.pageData.get(route_key) || default_value;
18
+ return result;
19
+ }
20
+
21
+ private static delPageData(route_key: string) {
22
+ PageData.pageData.delete(route_key);
23
+ }
24
+
25
+ private static delPagePromise(route_key: string) {
26
+ PageData.pagePromise.delete(route_key);
27
+ }
28
+
29
+ static setPageData(route_key: string, data: any) {
30
+ this.pageData.set(route_key, data);
31
+ }
32
+
33
+ static setPagePromise(
34
+ route_key: string,
35
+ options: {
36
+ res: (val: any) => void;
37
+ rej: (err: any) => void;
38
+ },
39
+ ) {
40
+ this.pagePromise.set(route_key, options);
41
+ }
42
+
43
+ static emitBack(route_key: string) {
44
+ const pme = PageData.pagePromise.get(route_key);
45
+ if (!pme) return;
46
+ const result = PageData.backResult.get(route_key);
47
+
48
+ PageData.delPageData(route_key);
49
+ PageData.delPagePromise(route_key);
50
+
51
+ if (result) {
52
+ PageData.backResult.delete(route_key);
53
+ if (result instanceof Error) {
54
+ pme.rej(result);
55
+ } else {
56
+ pme.res(result);
57
+ }
58
+ } else {
59
+ pme.res(null);
60
+ }
61
+ }
62
+
63
+ static setBackResult(result: any) {
64
+ const route_key = getCurrentRouteKey();
65
+ PageData.backResult.set(route_key, result);
66
+ }
67
+ }