@fukict/router 0.1.0

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 (58) hide show
  1. package/LICENSE +21 -0
  2. package/dist/Link.d.ts +38 -0
  3. package/dist/Link.d.ts.map +1 -0
  4. package/dist/Link.js +138 -0
  5. package/dist/Link.js.map +1 -0
  6. package/dist/RouteComponent.d.ts +85 -0
  7. package/dist/RouteComponent.d.ts.map +1 -0
  8. package/dist/RouteComponent.js +153 -0
  9. package/dist/RouteComponent.js.map +1 -0
  10. package/dist/Router.d.ts +128 -0
  11. package/dist/Router.d.ts.map +1 -0
  12. package/dist/Router.js +417 -0
  13. package/dist/Router.js.map +1 -0
  14. package/dist/RouterProvider.d.ts +41 -0
  15. package/dist/RouterProvider.d.ts.map +1 -0
  16. package/dist/RouterProvider.js +104 -0
  17. package/dist/RouterProvider.js.map +1 -0
  18. package/dist/RouterView.d.ts +27 -0
  19. package/dist/RouterView.d.ts.map +1 -0
  20. package/dist/RouterView.js +66 -0
  21. package/dist/RouterView.js.map +1 -0
  22. package/dist/history/base.d.ts +45 -0
  23. package/dist/history/base.d.ts.map +1 -0
  24. package/dist/history/base.js +47 -0
  25. package/dist/history/base.js.map +1 -0
  26. package/dist/history/browser.d.ts +17 -0
  27. package/dist/history/browser.d.ts.map +1 -0
  28. package/dist/history/browser.js +76 -0
  29. package/dist/history/browser.js.map +1 -0
  30. package/dist/history/hash.d.ts +14 -0
  31. package/dist/history/hash.d.ts.map +1 -0
  32. package/dist/history/hash.js +51 -0
  33. package/dist/history/hash.js.map +1 -0
  34. package/dist/history/index.d.ts +12 -0
  35. package/dist/history/index.d.ts.map +1 -0
  36. package/dist/history/index.js +16 -0
  37. package/dist/history/index.js.map +1 -0
  38. package/dist/history/types.d.ts +34 -0
  39. package/dist/history/types.d.ts.map +1 -0
  40. package/dist/history/types.js +2 -0
  41. package/dist/history/types.js.map +1 -0
  42. package/dist/index.d.ts +15 -0
  43. package/dist/index.d.ts.map +1 -0
  44. package/dist/index.js +16 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/matcher.d.ts +59 -0
  47. package/dist/matcher.d.ts.map +1 -0
  48. package/dist/matcher.js +213 -0
  49. package/dist/matcher.js.map +1 -0
  50. package/dist/metadata.d.ts +14 -0
  51. package/dist/metadata.d.ts.map +1 -0
  52. package/dist/metadata.js +14 -0
  53. package/dist/metadata.js.map +1 -0
  54. package/dist/types.d.ts +331 -0
  55. package/dist/types.d.ts.map +1 -0
  56. package/dist/types.js +2 -0
  57. package/dist/types.js.map +1 -0
  58. package/package.json +54 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Fukict Team
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/dist/Link.d.ts ADDED
@@ -0,0 +1,38 @@
1
+ import { Fukict, type VNode } from '@fukict/basic';
2
+ import type { LinkProps } from './types';
3
+ /**
4
+ * Link 组件
5
+ *
6
+ * 路由导航链接组件
7
+ */
8
+ export declare class Link extends Fukict<LinkProps> {
9
+ /**
10
+ * 获取 Router 实例
11
+ */
12
+ private getRouter;
13
+ /**
14
+ * 构建完整路径
15
+ */
16
+ private buildPath;
17
+ /**
18
+ * 构建 href 属性(根据路由模式)
19
+ */
20
+ private buildHref;
21
+ /**
22
+ * 检查路径是否激活
23
+ */
24
+ private isActive;
25
+ /**
26
+ * 检查路径是否精确激活
27
+ */
28
+ private isExactActive;
29
+ /**
30
+ * 处理点击事件
31
+ */
32
+ private handleClick;
33
+ /**
34
+ * 渲染方法
35
+ */
36
+ render(): VNode;
37
+ }
38
+ //# sourceMappingURL=Link.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Link.d.ts","sourceRoot":"","sources":["../src/Link.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,KAAK,EAAK,MAAM,eAAe,CAAC;AAGtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC;;;;GAIG;AACH,qBAAa,IAAK,SAAQ,MAAM,CAAC,SAAS,CAAC;IACzC;;OAEG;IACH,OAAO,CAAC,SAAS;IAIjB;;OAEG;IACH,OAAO,CAAC,SAAS;IAkCjB;;OAEG;IACH,OAAO,CAAC,SAAS;IAqBjB;;OAEG;IACH,OAAO,CAAC,QAAQ;IAahB;;OAEG;IACH,OAAO,CAAC,aAAa;IAYrB;;OAEG;IACH,OAAO,CAAC,WAAW,CAiBjB;IAEF;;OAEG;IACH,MAAM,IAAI,KAAK;CAuChB"}
package/dist/Link.js ADDED
@@ -0,0 +1,138 @@
1
+ import { Fukict, h } from '@fukict/basic';
2
+ import { Router } from './Router';
3
+ /**
4
+ * Link 组件
5
+ *
6
+ * 路由导航链接组件
7
+ */
8
+ export class Link extends Fukict {
9
+ /**
10
+ * 获取 Router 实例
11
+ */
12
+ getRouter() {
13
+ return Router.getInstance();
14
+ }
15
+ /**
16
+ * 构建完整路径
17
+ */
18
+ buildPath() {
19
+ const { to } = this.props;
20
+ if (typeof to === 'string') {
21
+ return to;
22
+ }
23
+ const router = this.getRouter();
24
+ if (!router) {
25
+ return '/';
26
+ }
27
+ let path = to.path || router.currentRoute.path;
28
+ // 添加查询参数
29
+ if (to.query) {
30
+ const params = new URLSearchParams();
31
+ for (const [key, value] of Object.entries(to.query)) {
32
+ params.append(key, value);
33
+ }
34
+ const queryString = params.toString();
35
+ if (queryString) {
36
+ path += '?' + queryString;
37
+ }
38
+ }
39
+ // 添加 hash
40
+ if (to.hash) {
41
+ path += to.hash;
42
+ }
43
+ return path;
44
+ }
45
+ /**
46
+ * 构建 href 属性(根据路由模式)
47
+ */
48
+ buildHref() {
49
+ const path = this.buildPath();
50
+ const router = this.getRouter();
51
+ if (!router) {
52
+ return path;
53
+ }
54
+ // 获取路由模式(通过 router 的 history 实例判断)
55
+ // @ts-ignore - 访问私有属性
56
+ const history = router.history;
57
+ // 如果是 HashHistory,则在路径前加 #
58
+ if (history && history.constructor.name === 'HashHistory') {
59
+ return `#${path}`;
60
+ }
61
+ // history 模式直接返回路径
62
+ return path;
63
+ }
64
+ /**
65
+ * 检查路径是否激活
66
+ */
67
+ isActive() {
68
+ const router = this.getRouter();
69
+ if (!router) {
70
+ return false;
71
+ }
72
+ const targetPath = this.buildPath();
73
+ const currentPath = router.currentRoute.path;
74
+ // 简单的路径匹配(可以优化为更精确的匹配)
75
+ return currentPath.startsWith(targetPath);
76
+ }
77
+ /**
78
+ * 检查路径是否精确激活
79
+ */
80
+ isExactActive() {
81
+ const router = this.getRouter();
82
+ if (!router) {
83
+ return false;
84
+ }
85
+ const targetPath = this.buildPath();
86
+ const currentPath = router.currentRoute.path;
87
+ return currentPath === targetPath;
88
+ }
89
+ /**
90
+ * 处理点击事件
91
+ */
92
+ handleClick = (e) => {
93
+ // 阻止默认行为
94
+ e.preventDefault();
95
+ const router = this.getRouter();
96
+ if (!router) {
97
+ return;
98
+ }
99
+ const { to, replace } = this.props;
100
+ // 导航
101
+ if (replace) {
102
+ router.replace(to);
103
+ }
104
+ else {
105
+ router.push(to);
106
+ }
107
+ };
108
+ /**
109
+ * 渲染方法
110
+ */
111
+ render() {
112
+ const { activeClass = 'router-link-active', exactActiveClass = 'router-link-exact-active', } = this.props;
113
+ const href = this.buildHref();
114
+ const isActive = this.isActive();
115
+ const isExactActive = this.isExactActive();
116
+ // 构建 class 列表
117
+ const classes = ['router-link'];
118
+ if (this.props.class) {
119
+ classes.push(this.props.class);
120
+ }
121
+ if (isActive) {
122
+ classes.push(activeClass);
123
+ }
124
+ if (isExactActive) {
125
+ classes.push(exactActiveClass);
126
+ }
127
+ return h('a', {
128
+ href,
129
+ class: classes.join(' '),
130
+ 'on:click': this.handleClick,
131
+ }, Array.isArray(this.slots.default)
132
+ ? this.slots.default
133
+ : this.slots.default
134
+ ? [this.slots.default]
135
+ : []);
136
+ }
137
+ }
138
+ //# sourceMappingURL=Link.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Link.js","sourceRoot":"","sources":["../src/Link.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,85 @@
1
+ import { Fukict, type VNode } from '@fukict/basic';
2
+ import type { Router } from './Router';
3
+ import type { Location, Route, RouteConfig, RouteMeta, RouteProps } from './types';
4
+ /**
5
+ * 路由组件基类
6
+ *
7
+ * 提供路由相关的上下文和工具方法
8
+ */
9
+ export declare abstract class RouteComponent extends Fukict<RouteProps> {
10
+ /**
11
+ * Router 实例
12
+ */
13
+ get router(): Router;
14
+ /**
15
+ * 当前匹配的路由配置
16
+ */
17
+ get matched(): RouteConfig | null;
18
+ /**
19
+ * 当前路由对象
20
+ */
21
+ get route(): Route;
22
+ /**
23
+ * 路由参数(如 { id: '123' })
24
+ */
25
+ get params(): Record<string, string>;
26
+ /**
27
+ * 查询参数(如 { page: '1' })
28
+ */
29
+ get query(): Record<string, string>;
30
+ /**
31
+ * 路由元信息
32
+ */
33
+ get meta(): RouteMeta;
34
+ /**
35
+ * 导航到指定路径(添加历史记录)
36
+ */
37
+ push(location: string | Location): void;
38
+ /**
39
+ * 替换当前路由(不添加历史记录)
40
+ */
41
+ replace(location: string | Location): void;
42
+ /**
43
+ * 返回上一页
44
+ */
45
+ back(): void;
46
+ /**
47
+ * 前进到下一页
48
+ */
49
+ forward(): void;
50
+ /**
51
+ * 更新查询参数(保留其他参数)
52
+ */
53
+ updateQuery(query: Record<string, string>): void;
54
+ /**
55
+ * 更新路由参数
56
+ */
57
+ updateParams(params: Record<string, string>): void;
58
+ /**
59
+ * 路由参数变化时的钩子
60
+ * 子类可以重写此方法
61
+ */
62
+ routeParamsChanged?(newParams: Record<string, string>, oldParams: Record<string, string>): void;
63
+ /**
64
+ * 查询参数变化时的钩子
65
+ * 子类可以重写此方法
66
+ */
67
+ routeQueryChanged?(newQuery: Record<string, string>, oldQuery: Record<string, string>): void;
68
+ /**
69
+ * 重写 update 方法,添加参数变化检测
70
+ */
71
+ update(props: RouteProps): void;
72
+ /**
73
+ * 比较两个参数对象是否相等
74
+ */
75
+ private isParamsEqual;
76
+ /**
77
+ * 比较两个查询参数对象是否相等
78
+ */
79
+ private isQueryEqual;
80
+ /**
81
+ * 渲染方法(子类必须实现)
82
+ */
83
+ abstract render(): VNode;
84
+ }
85
+ //# sourceMappingURL=RouteComponent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RouteComponent.d.ts","sourceRoot":"","sources":["../src/RouteComponent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,KAAK,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,KAAK,EACV,QAAQ,EACR,KAAK,EACL,WAAW,EAEX,SAAS,EACT,UAAU,EACX,MAAM,SAAS,CAAC;AAEjB;;;;GAIG;AACH,8BAAsB,cAAe,SAAQ,MAAM,CAAC,UAAU,CAAC;IAC7D;;OAEG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,WAAW,GAAG,IAAI,CAEhC;IAED;;OAEG;IACH,IAAI,KAAK,IAAI,KAAK,CAEjB;IAED;;OAEG;IACH,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAEnC;IAED;;OAEG;IACH,IAAI,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAElC;IAED;;OAEG;IACH,IAAI,IAAI,IAAI,SAAS,CAEpB;IAED;;OAEG;IACH,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI;IAIvC;;OAEG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI;IAI1C;;OAEG;IACH,IAAI,IAAI,IAAI;IAIZ;;OAEG;IACH,OAAO,IAAI,IAAI;IAIf;;OAEG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAWhD;;OAEG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAmBlD;;;OAGG;IACH,kBAAkB,CAAC,CACjB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACjC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,IAAI;IAEP;;;OAGG;IACH,iBAAiB,CAAC,CAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAChC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC/B,IAAI;IAEP;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAsB/B;;OAEG;IACH,OAAO,CAAC,aAAa;IAoBrB;;OAEG;IACH,OAAO,CAAC,YAAY;IAoBpB;;OAEG;IACH,QAAQ,CAAC,MAAM,IAAI,KAAK;CACzB"}
@@ -0,0 +1,153 @@
1
+ import { Fukict } from '@fukict/basic';
2
+ /**
3
+ * 路由组件基类
4
+ *
5
+ * 提供路由相关的上下文和工具方法
6
+ */
7
+ export class RouteComponent extends Fukict {
8
+ /**
9
+ * Router 实例
10
+ */
11
+ get router() {
12
+ return this.props.router;
13
+ }
14
+ /**
15
+ * 当前匹配的路由配置
16
+ */
17
+ get matched() {
18
+ return this.router.matched;
19
+ }
20
+ /**
21
+ * 当前路由对象
22
+ */
23
+ get route() {
24
+ return this.router.currentRoute;
25
+ }
26
+ /**
27
+ * 路由参数(如 { id: '123' })
28
+ */
29
+ get params() {
30
+ return this.route.params;
31
+ }
32
+ /**
33
+ * 查询参数(如 { page: '1' })
34
+ */
35
+ get query() {
36
+ return this.route.query;
37
+ }
38
+ /**
39
+ * 路由元信息
40
+ */
41
+ get meta() {
42
+ return this.route.meta;
43
+ }
44
+ /**
45
+ * 导航到指定路径(添加历史记录)
46
+ */
47
+ push(location) {
48
+ this.router.push(location);
49
+ }
50
+ /**
51
+ * 替换当前路由(不添加历史记录)
52
+ */
53
+ replace(location) {
54
+ this.router.replace(location);
55
+ }
56
+ /**
57
+ * 返回上一页
58
+ */
59
+ back() {
60
+ this.router.back();
61
+ }
62
+ /**
63
+ * 前进到下一页
64
+ */
65
+ forward() {
66
+ this.router.forward();
67
+ }
68
+ /**
69
+ * 更新查询参数(保留其他参数)
70
+ */
71
+ updateQuery(query) {
72
+ this.push({
73
+ path: this.route.path,
74
+ query: {
75
+ ...this.route.query,
76
+ ...query,
77
+ },
78
+ hash: this.route.hash,
79
+ });
80
+ }
81
+ /**
82
+ * 更新路由参数
83
+ */
84
+ updateParams(params) {
85
+ const matched = this.matched;
86
+ if (!matched) {
87
+ return;
88
+ }
89
+ // 使用新参数构建路径
90
+ let path = matched.path;
91
+ for (const [key, value] of Object.entries(params)) {
92
+ path = path.replace(`:${key}`, value);
93
+ }
94
+ this.push({
95
+ path,
96
+ query: this.route.query,
97
+ hash: this.route.hash,
98
+ });
99
+ }
100
+ /**
101
+ * 重写 update 方法,添加参数变化检测
102
+ */
103
+ update(props) {
104
+ const oldParams = this.params;
105
+ const oldQuery = this.query;
106
+ // 调用父类的 update
107
+ super.update(props);
108
+ // 检测参数变化
109
+ const newParams = this.params;
110
+ const newQuery = this.query;
111
+ // 检测路由参数变化
112
+ if (this.routeParamsChanged && !this.isParamsEqual(oldParams, newParams)) {
113
+ this.routeParamsChanged(newParams, oldParams);
114
+ }
115
+ // 检测查询参数变化
116
+ if (this.routeQueryChanged && !this.isQueryEqual(oldQuery, newQuery)) {
117
+ this.routeQueryChanged(newQuery, oldQuery);
118
+ }
119
+ }
120
+ /**
121
+ * 比较两个参数对象是否相等
122
+ */
123
+ isParamsEqual(params1, params2) {
124
+ const keys1 = Object.keys(params1);
125
+ const keys2 = Object.keys(params2);
126
+ if (keys1.length !== keys2.length) {
127
+ return false;
128
+ }
129
+ for (const key of keys1) {
130
+ if (params1[key] !== params2[key]) {
131
+ return false;
132
+ }
133
+ }
134
+ return true;
135
+ }
136
+ /**
137
+ * 比较两个查询参数对象是否相等
138
+ */
139
+ isQueryEqual(query1, query2) {
140
+ const keys1 = Object.keys(query1);
141
+ const keys2 = Object.keys(query2);
142
+ if (keys1.length !== keys2.length) {
143
+ return false;
144
+ }
145
+ for (const key of keys1) {
146
+ if (query1[key] !== query2[key]) {
147
+ return false;
148
+ }
149
+ }
150
+ return true;
151
+ }
152
+ }
153
+ //# sourceMappingURL=RouteComponent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RouteComponent.js","sourceRoot":"","sources":["../src/RouteComponent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,128 @@
1
+ import type { Location, NavigationGuard, Route, RouteConfig, RouterOptions } from './types';
2
+ /**
3
+ * 路由变化监听器类型
4
+ */
5
+ type RouteListener = () => void;
6
+ /**
7
+ * Router 类
8
+ */
9
+ export declare class Router {
10
+ /**
11
+ * 全局单例
12
+ */
13
+ private static instance;
14
+ /**
15
+ * History 管理器
16
+ */
17
+ private history;
18
+ /**
19
+ * 路由匹配器
20
+ */
21
+ private matcher;
22
+ /**
23
+ * 当前路由
24
+ */
25
+ currentRoute: Route;
26
+ /**
27
+ * 路由变化监听器列表
28
+ */
29
+ private listeners;
30
+ /**
31
+ * 全局前置守卫
32
+ */
33
+ private beforeEachGuards;
34
+ /**
35
+ * 全局后置钩子
36
+ */
37
+ private afterEachHooks;
38
+ /**
39
+ * 路由深度(用于嵌套路由)
40
+ */
41
+ private depth;
42
+ /**
43
+ * 配置选项
44
+ */
45
+ private options;
46
+ /**
47
+ * 构造函数
48
+ * @param options 路由配置选项
49
+ * @param depth 路由深度(用于嵌套路由,内部使用)
50
+ */
51
+ constructor(options: RouterOptions, depth?: number);
52
+ /**
53
+ * 获取全局 Router 实例
54
+ */
55
+ static getInstance(): Router | null;
56
+ /**
57
+ * 获取当前深度匹配的路由配置
58
+ */
59
+ get matched(): RouteConfig | null;
60
+ /**
61
+ * 创建子路由(depth + 1)
62
+ */
63
+ createChild(): Router;
64
+ /**
65
+ * 清理资源
66
+ */
67
+ destroy(): void;
68
+ /**
69
+ * 导航到指定路径(由 RouterProvider 调用)
70
+ * 包含守卫逻辑
71
+ */
72
+ navigate(path: string): Promise<void>;
73
+ /**
74
+ * 更新路由状态(由 history 监听器调用)
75
+ * 不修改 history,只更新内部状态和执行守卫
76
+ */
77
+ updateRoute(path: string): Promise<void>;
78
+ /**
79
+ * 创建路由对象
80
+ */
81
+ private createRoute;
82
+ /**
83
+ * 解析 Location 字符串
84
+ */
85
+ private parseLocation;
86
+ /**
87
+ * 构建完整路径
88
+ */
89
+ private buildPath;
90
+ /**
91
+ * 序列化查询参数
92
+ */
93
+ private stringifyQuery;
94
+ /**
95
+ * 导航到指定路径(添加历史记录)
96
+ */
97
+ push(location: string | Location): void;
98
+ /**
99
+ * 替换当前路由(不添加历史记录)
100
+ */
101
+ replace(location: string | Location): void;
102
+ /**
103
+ * 返回上一页
104
+ */
105
+ back(): void;
106
+ /**
107
+ * 前进到下一页
108
+ */
109
+ forward(): void;
110
+ /**
111
+ * 注册前置守卫
112
+ */
113
+ beforeEach(guard: NavigationGuard): void;
114
+ /**
115
+ * 注册后置钩子
116
+ */
117
+ afterEach(hook: (to: Route, from: Route) => void): void;
118
+ /**
119
+ * 订阅路由变化
120
+ */
121
+ subscribe(listener: RouteListener): () => void;
122
+ /**
123
+ * 通知监听器
124
+ */
125
+ private notify;
126
+ }
127
+ export {};
128
+ //# sourceMappingURL=Router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Router.d.ts","sourceRoot":"","sources":["../src/Router.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,QAAQ,EACR,eAAe,EACf,KAAK,EACL,WAAW,EACX,aAAa,EACd,MAAM,SAAS,CAAC;AAEjB;;GAEG;AACH,KAAK,aAAa,GAAG,MAAM,IAAI,CAAC;AAEhC;;GAEG;AACH,qBAAa,MAAM;IACjB;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAuB;IAE9C;;OAEG;IACH,OAAO,CAAC,OAAO,CAAW;IAE1B;;OAEG;IACH,OAAO,CAAC,OAAO,CAAe;IAE9B;;OAEG;IACI,YAAY,EAAE,KAAK,CAAC;IAE3B;;OAEG;IACH,OAAO,CAAC,SAAS,CAAiC;IAElD;;OAEG;IACH,OAAO,CAAC,gBAAgB,CAAyB;IAEjD;;OAEG;IACH,OAAO,CAAC,cAAc,CAA+C;IAErE;;OAEG;IACH,OAAO,CAAC,KAAK,CAAS;IAEtB;;OAEG;IACH,OAAO,CAAC,OAAO,CAAgB;IAE/B;;;;OAIG;gBACS,OAAO,EAAE,aAAa,EAAE,KAAK,GAAE,MAAU;IAyCrD;;OAEG;IACH,MAAM,CAAC,WAAW,IAAI,MAAM,GAAG,IAAI;IAInC;;OAEG;IACH,IAAI,OAAO,IAAI,WAAW,GAAG,IAAI,CAEhC;IAED;;OAEG;IACH,WAAW,IAAI,MAAM;IASrB;;OAEG;IACH,OAAO,IAAI,IAAI;IASf;;;OAGG;IACG,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA6E3C;;;OAGG;IACG,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA6E9C;;OAEG;IACH,OAAO,CAAC,WAAW;IAkDnB;;OAEG;IACH,OAAO,CAAC,aAAa;IAiCrB;;OAEG;IACH,OAAO,CAAC,SAAS;IAuBjB;;OAEG;IACH,OAAO,CAAC,cAAc;IAUtB;;OAEG;IACH,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI;IAKvC;;OAEG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI;IAK1C;;OAEG;IACH,IAAI,IAAI,IAAI;IAIZ;;OAEG;IACH,OAAO,IAAI,IAAI;IAIf;;OAEG;IACH,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAIxC;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI;IAIvD;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,IAAI;IAS9C;;OAEG;IACH,OAAO,CAAC,MAAM;CAKf"}