vitarx-router 0.0.1 → 1.0.0-beta.2

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.
package/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  # VitarxRouter
2
2
 
3
+ Vitarx前端框架的配套路由器
3
4
  ________________________________________________________________________
4
5
 
5
6
  ## 安装
@@ -8,7 +9,40 @@ ________________________________________________________________________
8
9
  npm install vitarx-router
9
10
  ```
10
11
 
11
- ## 使用
12
- ```javascript
13
- import { Router } from 'vitarx-router'
12
+ ## 简单示例
13
+
14
+ ```ts
15
+ // main.ts
16
+ import { createRouter } from 'vitarx-router'
17
+ import Page1 from './Page/Page1.js'
18
+
19
+ createRouter({
20
+ mode: 'path', // 路由模式,可选值:hash、path、memory
21
+ suffix: '*', // 允许任何后缀,例如 /x.html
22
+ routes: [
23
+ {
24
+ name: 'home', // 命名路由
25
+ path: '/',
26
+ widget: lazy(() => import('./Pages/home.js')),// 代码分块懒加载
27
+ children: [ // 嵌套路由
28
+ {
29
+ path: '/workbench',
30
+ widget: lazy(() => import('./Pages/home/workbench.js')) // 直接使用小部件
31
+ }
32
+ ]
33
+ },
34
+ { // 动态路由
35
+ path: '/page1/{name?}',// {name?}为可选参数,没有?为必填参数
36
+ widget: Page1
37
+ },
38
+ { // 命名视图
39
+ path: '/page3',
40
+ widget: { // 命名视图
41
+ 'default': lazy(() => import('./Page/xxx.js')),
42
+ 'right': lazy(() => import('./Page/xxx.js'))
43
+ }
44
+ }
45
+ ]
46
+ })
47
+ createApp('#root').render(App)
14
48
  ```
@@ -3,4 +3,5 @@ export { NavigateStatus } from './type.js';
3
3
  export { default as Router } from './router.js';
4
4
  export { default as WebHistoryRouter } from './web-history-router.js';
5
5
  export { default as MemoryRouter } from './memory-router.js';
6
+ export { generateRouteIndex } from './utils.js';
6
7
  export * from './helper.js';
@@ -223,6 +223,22 @@ export default abstract class Router {
223
223
  * @return {RouteNormalized | undefined}
224
224
  */
225
225
  findParentRoute(route: RouteNormalized): RouteNormalized | undefined;
226
+ /**
227
+ * 根据路由目标创建导航数据
228
+ *
229
+ * @param {RouteTarget} target - 路由目标
230
+ */
231
+ createRouteLocation(target: RouteTarget): RouteLocation;
232
+ /**
233
+ * 路由跳转的通用方法
234
+ *
235
+ * `push`|`replace`方法最终都会调用此方法
236
+ *
237
+ * @protected
238
+ * @param {RouteTarget} target - 目标
239
+ * @return {Promise<NavigateResult>} - 是否导航成功
240
+ */
241
+ navigate(target: RouteTarget): Promise<NavigateResult>;
226
242
  /**
227
243
  * 该方法提供给`RouterView`完成渲染时调用
228
244
  *
@@ -281,8 +297,9 @@ export default abstract class Router {
281
297
  * @param path - 路径
282
298
  * @param query - ?查询参数
283
299
  * @param hash - #哈希值
300
+ * @return {string}
284
301
  */
285
- protected makeFullPath(path: string, query: `?${string}` | '' | Record<string, string>, hash: HashStr): `${string}`;
302
+ protected makeFullPath(path: string, query: `?${string}` | '' | Record<string, string>, hash: HashStr): `/${string}`;
286
303
  /**
287
304
  * 添加历史记录
288
305
  *
@@ -309,13 +326,6 @@ export default abstract class Router {
309
326
  * @protected
310
327
  */
311
328
  protected isSameNavigate(to: RouteLocation, from: RouteLocation): boolean;
312
- /**
313
- * 根据路由目标创建导航数据
314
- *
315
- * @param {RouteTarget} target - 路由目标
316
- * @protected
317
- */
318
- protected createRouteLocation(target: RouteTarget): RouteLocation;
319
329
  /**
320
330
  * 触发路由前置守卫
321
331
  *
@@ -331,16 +341,6 @@ export default abstract class Router {
331
341
  * @param {DeepReadonly<RouteLocation>} from - 前路由对象
332
342
  */
333
343
  protected onAfterEach(to: DeepReadonly<RouteLocation>, from: DeepReadonly<RouteLocation>): void;
334
- /**
335
- * 路由跳转的通用方法
336
- *
337
- * 仅供内部使用,外部请使用`push`|`replace`方法
338
- *
339
- * @protected
340
- * @param {RouteTarget} target - 目标
341
- * @return {Promise<NavigateResult>} - 是否导航成功
342
- */
343
- protected navigate(target: RouteTarget): Promise<NavigateResult>;
344
344
  /**
345
345
  * 更新路由数据
346
346
  *
@@ -156,6 +156,14 @@ export interface RouteLocation {
156
156
  * @default {}
157
157
  */
158
158
  query: Record<string, string>;
159
+ /**
160
+ * 路由线路配置的元数据
161
+ *
162
+ * 如果没有配置元数据,那它将会是空对象,未匹配到任何路由也会是空对象。
163
+ *
164
+ * @default {}
165
+ */
166
+ meta: RouteMeta;
159
167
  /**
160
168
  * 匹配的路由对象
161
169
  *
@@ -320,12 +328,10 @@ export interface RouterOptions<T_MODE extends HistoryMode = HistoryMode> {
320
328
  /**
321
329
  * 支持的后缀名,如:.html、.md等。
322
330
  *
323
- * 默认支持所有后缀名进行匹配,如:`/page.html`、`/page.md`等。
324
- *
325
331
  * 可选值类型:
326
- * 1. 通配符:`*`:支持所有后缀名
332
+ * 1. 通配符:`*`:支持所有后缀名,如:`/page.html`、`/page.md`等。
327
333
  * 2. 字符串类型:`html`:支持html后缀名
328
- * 3. 数组:`['html','md']`:同时支持html和md后缀名
334
+ * 3. 数组:`['html','md']`:同时支持html和md后缀名,注意不要以`.`开头
329
335
  * 4. false:不做任何处理,硬性匹配。
330
336
  * @default false
331
337
  */
@@ -1,57 +1,57 @@
1
- var D = Object.defineProperty;
2
- var j = (e) => {
1
+ var q = Object.defineProperty;
2
+ var I = (e) => {
3
3
  throw TypeError(e);
4
4
  };
5
- var M = (e, t, i) => t in e ? D(e, t, { enumerable: !0, configurable: !0, writable: !0, value: i }) : e[t] = i;
6
- var l = (e, t, i) => M(e, typeof t != "symbol" ? t + "" : t, i), B = (e, t, i) => t.has(e) || j("Cannot " + i);
7
- var f = (e, t, i) => (B(e, t, "read from private field"), i ? i.call(e) : t.get(e)), x = (e, t, i) => t.has(e) ? j("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(e) : t.set(e, i), v = (e, t, i, n) => (B(e, t, "write to private field"), n ? n.call(e, i) : t.set(e, i), i);
8
- import { reactive as U, shallowReactive as G, createElement as V, LazyWidget as q, deepEqual as k, deepClone as K, Widget as J, shallowRef as Q, inject as X, provide as Z, watch as N, Fragment as tt } from "vitarx";
9
- var g = /* @__PURE__ */ ((e) => (e[e.success = 0] = "success", e[e.aborted = 1] = "aborted", e[e.cancelled = 2] = "cancelled", e[e.duplicated = 3] = "duplicated", e[e.not_matched = 4] = "not_matched", e[e.exception = 5] = "exception", e))(g || {});
10
- function T(e) {
5
+ var K = (e, t, i) => t in e ? q(e, t, { enumerable: !0, configurable: !0, writable: !0, value: i }) : e[t] = i;
6
+ var l = (e, t, i) => K(e, typeof t != "symbol" ? t + "" : t, i), H = (e, t, i) => t.has(e) || I("Cannot " + i);
7
+ var f = (e, t, i) => (H(e, t, "read from private field"), i ? i.call(e) : t.get(e)), _ = (e, t, i) => t.has(e) ? I("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(e) : t.set(e, i), v = (e, t, i, n) => (H(e, t, "write to private field"), n ? n.call(e, i) : t.set(e, i), i);
8
+ import { reactive as J, shallowReactive as Q, markRaw as k, createElement as V, LazyWidget as X, deepClone as Z, deepEqual as S, Widget as M, shallowRef as N, inject as tt, provide as et, watch as it, Fragment as nt, Computed as L, isString as st } from "vitarx";
9
+ var p = /* @__PURE__ */ ((e) => (e[e.success = 0] = "success", e[e.aborted = 1] = "aborted", e[e.cancelled = 2] = "cancelled", e[e.duplicated = 3] = "duplicated", e[e.not_matched = 4] = "not_matched", e[e.exception = 5] = "exception", e))(p || {});
10
+ function B(e) {
11
11
  return typeof e == "boolean" || typeof e == "function" || typeof e == "object" && e !== null;
12
12
  }
13
- function et(e) {
13
+ function rt(e) {
14
14
  if (e.widget === void 0) return;
15
15
  if (!("injectProps" in e)) {
16
- e.injectProps = I(e, !0);
16
+ e.injectProps = W(e, !0);
17
17
  return;
18
18
  }
19
19
  const t = e.injectProps;
20
20
  if (typeof t == "object")
21
- it(t) ? nt(e, t) : st(e, t);
22
- else if (T(t))
23
- e.injectProps = I(e, t);
21
+ ot(t) ? at(e, t) : ct(e, t);
22
+ else if (B(t))
23
+ e.injectProps = W(e, t);
24
24
  else
25
25
  throw new TypeError(
26
26
  `[Vitarx.Router][TYPE_ERROR]:${e.path} 路由线路配置的 injectProps 类型有误,它可以是布尔值、函数,亦或是一个{string:any}类型的对象。`
27
27
  );
28
28
  }
29
- function it(e) {
29
+ function ot(e) {
30
30
  return Object.keys(e).length === 1 && "default" in e;
31
31
  }
32
- function nt(e, t) {
33
- if (!T(t.default))
32
+ function at(e, t) {
33
+ if (!B(t.default))
34
34
  throw new TypeError(
35
35
  `[Vitarx.Router][TYPE_ERROR]:${e.path} 路由线路配置的 injectProps.default 类型有误,它可以是布尔值、函数,亦或是一个{string:any}类型的对象。`
36
36
  );
37
37
  }
38
- function st(e, t) {
38
+ function ct(e, t) {
39
39
  for (const i of Object.keys(e.widget))
40
40
  if (i in t) {
41
- if (!T(t[i]))
41
+ if (!B(t[i]))
42
42
  throw new TypeError(
43
43
  `[Vitarx.Router][TYPE_ERROR]:${e.path} 路由线路配置的 injectProps.${i} 类型有误,它可以是布尔值、函数,亦或是一个{string:any}类型的对象。`
44
44
  );
45
45
  } else
46
46
  t[i] = !0;
47
47
  }
48
- function I(e, t) {
48
+ function W(e, t) {
49
49
  const i = {};
50
50
  for (const n of Object.keys(e.widget))
51
51
  i[n] = t;
52
52
  return i;
53
53
  }
54
- function rt(e) {
54
+ function ht(e) {
55
55
  if (!("widget" in e)) {
56
56
  if (e.children.length === 0)
57
57
  throw new TypeError(
@@ -76,42 +76,42 @@ function rt(e) {
76
76
  `[Vitarx.Router][TYPE_ERROR]:${e.path} 路由线路配置的 widget 类型有误,它可以是函数式小部件、类小部件,亦或是一个惰性加载器。`
77
77
  );
78
78
  }
79
- const F = Symbol("LazyLoader");
80
- function O(e) {
79
+ const U = Symbol("LazyLoader");
80
+ function T(e) {
81
81
  return /\{[^}]+}/.test(e);
82
82
  }
83
- function ot(e) {
83
+ function ut(e) {
84
84
  const t = e.replace(/\s+/g, ""), i = /\{[\w-]+\?}/g, n = t.match(i);
85
85
  return n ? n.length : 0;
86
86
  }
87
- function H(e) {
87
+ function A(e) {
88
88
  return "children" in e && e.children !== void 0 && e.children.length > 0;
89
89
  }
90
- function ct(e, t, i, n) {
90
+ function lt(e, t, i, n) {
91
91
  let s = 0;
92
- const r = (h, c) => {
93
- const _ = t[h];
94
- if (_ ? _ instanceof RegExp || (console.warn(
92
+ const r = (h, a) => {
93
+ const $ = t[h];
94
+ if ($ ? $ instanceof RegExp || (console.warn(
95
95
  `[Vitarx.Router][WARN]:${e} 动态路径${h}变量的自定义正则表达式必须是 RegExp 类型`
96
- ), t[h] = n) : t[h] = n, c)
96
+ ), t[h] = n) : t[h] = n, a)
97
97
  return s++, `(?:(${t[h].source}))?`;
98
98
  if (s)
99
99
  throw new Error(
100
100
  `[Vitarx.Router][ERROR]:动态路径 ${e} 中,可选变量 ${h} 后不能存在任何必填变量`
101
101
  );
102
102
  return `(${t[h].source})`;
103
- }, o = e.replace(/{([^}?]+)\?}/g, (h, c) => r(c, !0)).replace(/{([^}]+)}/g, (h, c) => r(c, !1)).replace(/\//g, "\\/").replace(/\/?$/, "/?"), u = i ? "" : "i", a = e.replace(/^\/|\/$/g, "").split("/").length;
103
+ }, o = e.replace(/{([^}?]+)\?}/g, (h, a) => r(a, !0)).replace(/{([^}]+)}/g, (h, a) => r(a, !1)).replace(/\//g, "\\/").replace(/\/?$/, "/?"), u = i ? "" : "i", c = e.replace(/^\/|\/$/g, "").split("/").length;
104
104
  return {
105
105
  regex: new RegExp(`^${o}$`, u),
106
- length: a,
106
+ length: c,
107
107
  optional: s
108
108
  };
109
109
  }
110
- function d(e) {
111
- return e = e.replace(/\s+/g, "").replace(/\/+/g, "/"), e.length ? e === "/" || e === "/#/" ? e : e.replace(/\/$/, "") : "/";
110
+ function R(e) {
111
+ return e = `/${e}`.replace(/\s+/g, "").replace(/\/+/g, "/"), e.length ? e === "/" || e === "/#/" ? e : e.replace(/\/$/, "") : "/";
112
112
  }
113
- function S(e, t) {
114
- if (!O(e)) return e;
113
+ function C(e, t) {
114
+ if (!T(e)) return e;
115
115
  const i = e;
116
116
  return e = e.replace(/{([^}]+)\?*}/g, (n, s) => {
117
117
  const r = s.endsWith("?");
@@ -122,48 +122,56 @@ function S(e, t) {
122
122
  );
123
123
  }
124
124
  return String(t[s]).replace(/\s+/g, "_");
125
- }), d(e);
125
+ }), R(e);
126
126
  }
127
- function at(e) {
128
- return typeof e == "function" && e[F];
127
+ function ft(e) {
128
+ return typeof e == "function" && e[U];
129
129
  }
130
- function W(e, t) {
130
+ function D(e, t) {
131
131
  return typeof e != "string" || !e ? "" : (e = e.trim(), e.startsWith("#") ? e : `#${e}`);
132
132
  }
133
- function L(e) {
133
+ function z(e) {
134
134
  e = decodeURIComponent(e);
135
135
  const t = new URLSearchParams(
136
136
  e.startsWith("?") ? e.substring(1) : e
137
137
  ), i = {};
138
138
  return t.forEach((n, s) => i[s] = n), i;
139
139
  }
140
- function ht(e) {
140
+ function dt(e) {
141
141
  const t = new URLSearchParams(e).toString();
142
142
  return t ? `?${t}` : "";
143
143
  }
144
- function ut(e, t, i) {
145
- let n = decodeURIComponent(e.pathname), s = decodeURIComponent(e.hash), r;
146
- if (t === "path")
147
- return r = L(e.search), n.startsWith(i) ? n = d(n.slice(i.length)) : n = d(n), { index: n, hash: s, query: r };
148
- if (s.includes("#")) {
149
- const o = s.slice(1), [u, a] = o.split("#"), [h, c] = u.split("?");
150
- n = d(h || ""), s = a ? `#${a}` : "", r = L(c || "");
151
- } else
152
- n = i, r = L(e.search);
144
+ function pt(e, t, i) {
145
+ let n = decodeURIComponent(e.pathname), s = decodeURIComponent(e.hash), r = z(e.search);
146
+ if (n = R(n.startsWith(i) ? n.slice(i.length) : n), t === "hash" && s.includes("#/")) {
147
+ const o = s.slice(1), [u, c] = o.split("#"), [h, a] = u.split("?");
148
+ n = R(h || ""), s = c ? `#${c}` : "", r = z(a || "");
149
+ }
153
150
  return { index: n, hash: s, query: r };
154
151
  }
155
- function lt(e) {
156
- const t = Y(e);
152
+ function Rt(e) {
153
+ const t = G(e);
157
154
  return t && (e = e.slice(0, -t.length)), {
158
155
  path: e,
159
156
  suffix: t
160
157
  };
161
158
  }
162
- function Y(e) {
159
+ function G(e) {
163
160
  const t = e.match(/^(.*?)(\.[a-zA-Z0-9]+)$/);
164
161
  return t ? t[2] : "";
165
162
  }
166
- function ft(e) {
163
+ function bt(e) {
164
+ const t = [], i = [];
165
+ function n(s, r = "") {
166
+ const o = R(r ? `${r}/${s.path}` : s.path);
167
+ s.widget && t.push(o), s.name && i.push(s.name), s.children && s.children.length > 0 && s.children.forEach((u) => n(u, o));
168
+ }
169
+ return e.forEach((s) => n(s)), {
170
+ paths: t,
171
+ names: i
172
+ };
173
+ }
174
+ function gt(e) {
167
175
  if (typeof e != "object" || e === null) return !1;
168
176
  const t = [
169
177
  "index",
@@ -172,41 +180,42 @@ function ft(e) {
172
180
  "hash",
173
181
  "params",
174
182
  "query",
175
- "matched"
183
+ "matched",
184
+ "meta"
176
185
  ];
177
186
  for (const i of t)
178
187
  if (!Object.prototype.hasOwnProperty.call(e, i)) return !1;
179
188
  return !0;
180
189
  }
181
- function dt(e) {
190
+ function mt(e) {
182
191
  if (e.meta = e.meta || {}, e.pattern = e.pattern || {}, e.children = e.children || [], !Array.isArray(e.children))
183
192
  throw new TypeError(
184
193
  `[Vitarx.Router][TYPE_ERROR]:${e.path} 路由线路配置 children 类型错误,它必须是数组类型。`
185
194
  );
186
195
  if (!e.path.trim())
187
196
  throw new TypeError("[Vitarx.Router][TYPE_ERROR]:路由线路配置 path 不能为空");
188
- return e.path = d(e.path), rt(e), et(e), e;
197
+ return e.path = R(e.path), ht(e), rt(e), e;
189
198
  }
190
- const pt = ["path", "hash", "index", "fullPath"];
191
- function Rt(e, t) {
192
- gt(e.matched, t.matched), A(e.params, t.params), A(e.query, t.query);
193
- for (const i of pt)
199
+ const wt = ["path", "hash", "index", "fullPath"];
200
+ function yt(e, t) {
201
+ _t(e.matched, t.matched), j(e.params, t.params), j(e.query, t.query), j(e.meta, t.meta);
202
+ for (const i of wt)
194
203
  e[i] !== t[i] && (e[i] = t[i]);
195
204
  }
196
- function gt(e, t) {
205
+ function _t(e, t) {
197
206
  for (let i = 0; i < t.length; i++)
198
207
  e[i] !== t[i] && (e[i] = t[i]);
199
208
  e.length > t.length && (e.length = t.length);
200
209
  }
201
- function A(e, t) {
210
+ function j(e, t) {
202
211
  const i = Object.keys(e), n = Object.keys(t);
203
212
  for (const s of n)
204
- t.hasOwnProperty(s) && (e[s] = t[s]);
213
+ Object.prototype.hasOwnProperty.call(t, s) && (e[s] = t[s]);
205
214
  for (const s in i)
206
215
  s in t || delete e[s];
207
216
  }
208
217
  var m;
209
- const R = class R {
218
+ const g = class g {
210
219
  constructor(t) {
211
220
  // 配置
212
221
  l(this, "_options");
@@ -242,7 +251,7 @@ const R = class R {
242
251
  l(this, "_isBrowser", typeof window < "u" && typeof window.document < "u");
243
252
  // 滚动行为
244
253
  l(this, "_scrollBehavior", "auto");
245
- if (f(R, m))
254
+ if (f(g, m))
246
255
  throw new Error("[Vitarx.Router.constructor]:路由器实例已存在,不能创建多个实例");
247
256
  this._options = {
248
257
  base: "/",
@@ -252,14 +261,15 @@ const R = class R {
252
261
  suffix: !1,
253
262
  pattern: /[\w.]+/,
254
263
  ...t
255
- }, this._options.base = `/${this._options.base.replace(/^\/+|\/+$/g, "")}`, this._currentRouteLocation = U({
264
+ }, this._options.base = `/${this._options.base.replace(/^\/+|\/+$/g, "")}`, this._currentRouteLocation = J({
256
265
  index: this._options.base,
257
266
  path: this._options.base,
258
267
  hash: "",
259
268
  fullPath: this._options.base,
260
269
  params: {},
261
270
  query: {},
262
- matched: G([])
271
+ matched: Q([]),
272
+ meta: k({})
263
273
  });
264
274
  }
265
275
  /**
@@ -268,9 +278,9 @@ const R = class R {
268
278
  * @return {Router} - 路由器实例
269
279
  */
270
280
  static get instance() {
271
- if (!f(R, m))
281
+ if (!f(g, m))
272
282
  throw new Error("[Vitarx.Router.instance]:路由器实例未初始化");
273
- return f(R, m);
283
+ return f(g, m);
274
284
  }
275
285
  /**
276
286
  * 是否运行在浏览器端
@@ -354,7 +364,7 @@ const R = class R {
354
364
  * @return {boolean} - 如果初始化完成,返回true,否则返回false
355
365
  */
356
366
  get initialized() {
357
- return f(R, m) !== void 0;
367
+ return f(g, m) !== void 0;
358
368
  }
359
369
  /**
360
370
  * 受支持的`path`后缀名
@@ -408,9 +418,9 @@ const R = class R {
408
418
  */
409
419
  static routeView(t, i) {
410
420
  const n = t.widget;
411
- if (!n.hasOwnProperty(i)) return;
421
+ if (!Object.prototype.hasOwnProperty.call(n, i)) return;
412
422
  const s = n[i];
413
- return at(s) ? V(q, { children: s, key: t.path }) : V(s);
423
+ return ft(s) ? V(X, { children: s, key: t.path }) : V(s);
414
424
  }
415
425
  /**
416
426
  * 后退到上一个历史记录
@@ -451,7 +461,7 @@ const R = class R {
451
461
  removeRoute(t, i = !0) {
452
462
  const n = this.findRoute(t);
453
463
  if (n) {
454
- if (H(n))
464
+ if (A(n))
455
465
  for (const s of n.children)
456
466
  this.removeRoute(s.path, !1);
457
467
  this._pathRoutes.delete(n.path), n.name && this._namedRoutes.delete(n.name), this.removeDynamicRoute(n.path), i && this.removedFromRoutes(n);
@@ -509,7 +519,7 @@ const R = class R {
509
519
  * @return {this} - 返回当前路由器实例
510
520
  */
511
521
  initialize() {
512
- return f(R, m) ? this : (this.setupRoutes(this._options.routes), typeof this.options.scrollBehavior == "function" ? this._scrollBehaviorHandler = this.options.scrollBehavior : this._scrollBehavior = this.options.scrollBehavior, this.initializeRouter(), v(R, m, this), this);
522
+ return f(g, m) ? this : (this.setupRoutes(this._options.routes), typeof this.options.scrollBehavior == "function" ? this._scrollBehaviorHandler = this.options.scrollBehavior : this._scrollBehavior = this.options.scrollBehavior, this.initializeRouter(), v(g, m, this), this);
513
523
  }
514
524
  /**
515
525
  * 此方法用于浏览器端滚动到指定位置
@@ -541,6 +551,76 @@ const R = class R {
541
551
  findParentRoute(t) {
542
552
  return this._parentRoute.get(t);
543
553
  }
554
+ /**
555
+ * 根据路由目标创建导航数据
556
+ *
557
+ * @param {RouteTarget} target - 路由目标
558
+ */
559
+ createRouteLocation(t) {
560
+ if (gt(t)) return t;
561
+ const i = this.findRoute(t), { index: n, query: s = {}, params: r = {}, hash: o = "" } = t;
562
+ let u;
563
+ const c = [];
564
+ if (i) {
565
+ let O = G(n);
566
+ this.suffix && O && !i.path.endsWith(O) ? u = C(i.path + O, r) : u = C(i.path, r);
567
+ let P = this.findParentRoute(i);
568
+ for (; P; )
569
+ P.widget && c.unshift(P), P = this.findParentRoute(P);
570
+ c.push(i);
571
+ } else
572
+ u = R(n);
573
+ const h = (i == null ? void 0 : i.meta) || {}, a = D(o), $ = this.makeFullPath(u, s, a);
574
+ return { index: n, path: u, hash: a, fullPath: $, params: r, query: s, matched: c, meta: h };
575
+ }
576
+ /**
577
+ * 路由跳转的通用方法
578
+ *
579
+ * `push`|`replace`方法最终都会调用此方法
580
+ *
581
+ * @protected
582
+ * @param {RouteTarget} target - 目标
583
+ * @return {Promise<NavigateResult>} - 是否导航成功
584
+ */
585
+ navigate(t) {
586
+ const i = ++this._taskCounter;
587
+ this._currentTaskId = i;
588
+ const n = () => this._currentTaskId === i, s = Z(this.currentRouteLocation), r = async (o, u) => {
589
+ const c = this.createRouteLocation(o), h = (a = {}) => ({
590
+ from: s,
591
+ to: c,
592
+ status: p.success,
593
+ message: "导航成功",
594
+ redirectFrom: u ? t : void 0,
595
+ ...a
596
+ });
597
+ if (this.isSameNavigate(c, this.currentRouteLocation))
598
+ return h({
599
+ status: p.duplicated,
600
+ message: "导航到相同的路由,被系统阻止!"
601
+ });
602
+ try {
603
+ const a = await this.onBeforeEach(c, this.currentRouteLocation);
604
+ return a === !1 ? h({
605
+ status: p.aborted,
606
+ message: "导航被前置守卫钩子阻止"
607
+ }) : n() ? typeof a == "object" && a.index !== o.index ? (a.isReplace ?? (a.isReplace = !1), r(a, !0)) : c.matched.length ? (o.isReplace ? (this._pendingReplace = c, this.replaceHistory(c)) : (this._pendingPush = c, this.pushHistory(c)), h()) : h({
608
+ status: p.not_matched,
609
+ message: "未匹配到任何路由规则,被系统阻止!请检测目标索引是否正确。"
610
+ }) : h({
611
+ status: p.cancelled,
612
+ message: "已被新的导航请求替代,取消此次导航!"
613
+ });
614
+ } catch (a) {
615
+ return console.error("[Vitarx.Router.navigate][ERROR]:导航时捕获到了异常", a), h({
616
+ status: p.exception,
617
+ message: "导航时捕获到了异常",
618
+ error: a
619
+ });
620
+ }
621
+ };
622
+ return r(t, !1);
623
+ }
544
624
  /**
545
625
  * 该方法提供给`RouterView`完成渲染时调用
546
626
  *
@@ -580,7 +660,7 @@ const R = class R {
580
660
  * @protected
581
661
  */
582
662
  updateQuery(t) {
583
- k(this._currentRouteLocation.query, t) || (this._currentRouteLocation.query = t, this._currentRouteLocation.fullPath = this.makeFullPath(
663
+ S(this._currentRouteLocation.query, t) || (this._currentRouteLocation.query = t, this._currentRouteLocation.fullPath = this.makeFullPath(
584
664
  this._currentRouteLocation.path,
585
665
  t,
586
666
  this._currentRouteLocation.hash
@@ -596,7 +676,7 @@ const R = class R {
596
676
  */
597
677
  updateHash(t) {
598
678
  typeof t != "string" && console.warn(`[Vitarx.Router.updateHash][WARN]:hash值只能是字符串类型,给定${t}`);
599
- const i = W(t);
679
+ const i = D(t);
600
680
  i !== this._currentRouteLocation.hash && (this._currentRouteLocation.hash = i, this._currentRouteLocation.fullPath = this.makeFullPath(
601
681
  this._currentRouteLocation.path,
602
682
  this._currentRouteLocation.query,
@@ -612,8 +692,8 @@ const R = class R {
612
692
  * @return {MatchResult} 如果匹配失败则返回undefined
613
693
  */
614
694
  matchRoute(t) {
615
- if (t = d(t), this._options.strict || (t = t.toLowerCase()), this.suffix) {
616
- const { path: s, suffix: r } = lt(t);
695
+ if (t = R(t), this._options.strict || (t = t.toLowerCase()), this.suffix) {
696
+ const { path: s, suffix: r } = Rt(t);
617
697
  if (!this.isAllowedSuffix(r))
618
698
  return;
619
699
  t = s;
@@ -627,8 +707,8 @@ const R = class R {
627
707
  const o = s.exec(t);
628
708
  if (o) {
629
709
  const u = {};
630
- return Object.keys(r.pattern).forEach((h, c) => {
631
- u[h] = o[c + 1];
710
+ return Object.keys(r.pattern).forEach((h, a) => {
711
+ u[h] = o[a + 1];
632
712
  }), { route: r, params: u };
633
713
  }
634
714
  }
@@ -641,9 +721,10 @@ const R = class R {
641
721
  * @param path - 路径
642
722
  * @param query - ?查询参数
643
723
  * @param hash - #哈希值
724
+ * @return {string}
644
725
  */
645
726
  makeFullPath(t, i, n) {
646
- return n && !n.startsWith("#") && (n = `#${n}`), typeof i == "object" && (i = ht(i)), this.mode === "hash" ? d(`${this.basePath}/#${t}${i}${n}`) : d(`${this.basePath}${t}${i}${n}`);
727
+ return n && !n.startsWith("#") && (n = `#${n}`), typeof i == "object" && (i = dt(i)), this.mode === "hash" ? R(`${this.basePath}/#${t}${i}${n}`) : R(`${this.basePath}${t}${i}${n}`);
647
728
  }
648
729
  /**
649
730
  * 判断是否相同的导航请求
@@ -653,38 +734,7 @@ const R = class R {
653
734
  * @protected
654
735
  */
655
736
  isSameNavigate(t, i) {
656
- return k(t, i);
657
- }
658
- /**
659
- * 根据路由目标创建导航数据
660
- *
661
- * @param {RouteTarget} target - 路由目标
662
- * @protected
663
- */
664
- createRouteLocation(t) {
665
- if (ft(t)) return t;
666
- const i = this.findRoute(t), { index: n, query: s = {}, params: r = {}, hash: o = "" } = t;
667
- let u;
668
- const a = [];
669
- if (i) {
670
- let _ = Y(n);
671
- this.suffix && _ && !i.path.endsWith(_) ? u = S(i.path + _, r) : u = S(i.path, r);
672
- let E = this.findParentRoute(i);
673
- for (; E; )
674
- E.widget && a.unshift(E), E = this.findParentRoute(E);
675
- a.push(i);
676
- } else
677
- u = d(n);
678
- const h = W(o), c = this.makeFullPath(u, s, h);
679
- return {
680
- index: n,
681
- path: u,
682
- hash: h,
683
- fullPath: c,
684
- params: r,
685
- query: s,
686
- matched: a
687
- };
737
+ return S(t, i);
688
738
  }
689
739
  /**
690
740
  * 触发路由前置守卫
@@ -707,54 +757,6 @@ const R = class R {
707
757
  var n;
708
758
  return (n = this._options.afterEach) == null ? void 0 : n.call(this, t, i);
709
759
  }
710
- /**
711
- * 路由跳转的通用方法
712
- *
713
- * 仅供内部使用,外部请使用`push`|`replace`方法
714
- *
715
- * @protected
716
- * @param {RouteTarget} target - 目标
717
- * @return {Promise<NavigateResult>} - 是否导航成功
718
- */
719
- navigate(t) {
720
- const i = ++this._taskCounter;
721
- this._currentTaskId = i;
722
- const n = () => this._currentTaskId === i, s = K(this.currentRouteLocation), r = async (o, u) => {
723
- const a = this.createRouteLocation(o), h = (c = {}) => ({
724
- from: s,
725
- to: a,
726
- status: g.success,
727
- message: "导航成功",
728
- redirectFrom: u ? t : void 0,
729
- ...c
730
- });
731
- if (this.isSameNavigate(a, this.currentRouteLocation))
732
- return h({
733
- status: g.duplicated,
734
- message: "导航到相同的路由,被系统阻止!"
735
- });
736
- try {
737
- const c = await this.onBeforeEach(a, this.currentRouteLocation);
738
- return c === !1 ? h({
739
- status: g.aborted,
740
- message: "导航被前置守卫钩子阻止"
741
- }) : n() ? typeof c == "object" && c.index !== o.index ? (c.isReplace ?? (c.isReplace = !1), r(c, !0)) : a.matched.length ? (o.isReplace ? (this._pendingReplace = a, this.replaceHistory(a)) : (this._pendingPush = a, this.pushHistory(a)), h()) : h({
742
- status: g.not_matched,
743
- message: "未匹配到任何路由规则,被系统阻止!请检测目标索引是否正确。"
744
- }) : h({
745
- status: g.cancelled,
746
- message: "已被新的导航请求替代,取消此次导航!"
747
- });
748
- } catch (c) {
749
- return console.error("[Vitarx.Router.navigate][ERROR]:导航时捕获到了异常", c), h({
750
- status: g.exception,
751
- message: "导航时捕获到了异常",
752
- error: c
753
- });
754
- }
755
- };
756
- return r(t, !1);
757
- }
758
760
  /**
759
761
  * 更新路由数据
760
762
  *
@@ -762,7 +764,7 @@ const R = class R {
762
764
  * @param {RouteLocation} newLocation - 新的路由数据对象
763
765
  */
764
766
  updateRouteLocation(t) {
765
- Rt(this._currentRouteLocation, t);
767
+ yt(this._currentRouteLocation, t);
766
768
  }
767
769
  /**
768
770
  * 判断是否为允许的后缀
@@ -815,19 +817,19 @@ const R = class R {
815
817
  * @protected
816
818
  */
817
819
  removeDynamicRoute(t) {
818
- if (!O(t)) return;
820
+ if (!T(t)) return;
819
821
  const n = t.split("/").filter(Boolean).length, s = (o) => {
820
822
  const u = this._dynamicRoutes.get(o);
821
823
  if (u) {
822
- for (let a = 0; a < u.length; a++)
823
- if (u[a].route.path === t) {
824
- u.splice(a, 1);
824
+ for (let c = 0; c < u.length; c++)
825
+ if (u[c].route.path === t) {
826
+ u.splice(c, 1);
825
827
  break;
826
828
  }
827
829
  }
828
830
  };
829
831
  s(n);
830
- const r = ot(t);
832
+ const r = ut(t);
831
833
  if (r > 0)
832
834
  for (let o = 1; o <= r; o++)
833
835
  s(n - o);
@@ -849,8 +851,8 @@ const R = class R {
849
851
  * @protected
850
852
  */
851
853
  registerRoute(t, i) {
852
- const n = dt(t);
853
- if (i && (n.path = d(`${i.path}${n.path}`), this._parentRoute.set(n, i)), H(n)) {
854
+ const n = mt(t);
855
+ if (i && (n.path = R(`${i.path}${n.path}`), this._parentRoute.set(n, i)), A(n)) {
854
856
  t.widget && this.recordRoute(n);
855
857
  for (const s of n.children)
856
858
  this.registerRoute(s, n);
@@ -883,14 +885,14 @@ const R = class R {
883
885
  const i = this.strictPath(t.path);
884
886
  if (this._pathRoutes.has(i))
885
887
  throw new Error(`[Vitarx.Router][ERROR]:检测到重复的路由路径(path): ${t.path}`);
886
- this._pathRoutes.set(i, t), O(t.path) && this.recordDynamicRoute(t);
888
+ this._pathRoutes.set(i, t), T(t.path) && this.recordDynamicRoute(t);
887
889
  }
888
890
  /**
889
891
  * 添加动态路由
890
892
  * @param route
891
893
  */
892
894
  recordDynamicRoute(t) {
893
- const { regex: i, length: n, optional: s } = ct(
895
+ const { regex: i, length: n, optional: s } = lt(
894
896
  t.path,
895
897
  t.pattern,
896
898
  this.options.strict,
@@ -906,9 +908,9 @@ const R = class R {
906
908
  m = new WeakMap(), /**
907
909
  * 路由器实例,单例模式,用于全局获取路由器实例
908
910
  */
909
- x(R, m);
910
- let p = R;
911
- class mt extends p {
911
+ _(g, m);
912
+ let d = g;
913
+ class xt extends d {
912
914
  constructor(t) {
913
915
  super(t), ["path", "hash"].includes(t.mode) && (t.mode = "path"), t.mode === "hash" && this.ensureHash();
914
916
  }
@@ -918,7 +920,7 @@ class mt extends p {
918
920
  * @returns {RouteTarget} - 包含 index、hash 和 query 的对象
919
921
  */
920
922
  get currentRouteTarget() {
921
- return ut(window.location, this.mode, this.basePath);
923
+ return pt(window.location, this.mode, this.basePath);
922
924
  }
923
925
  /**
924
926
  * window.history
@@ -999,10 +1001,21 @@ class mt extends p {
999
1001
  hash: t.state.hash,
1000
1002
  query: t.state.query
1001
1003
  } : i = this.currentRouteTarget, this.replace(i).then((s) => {
1002
- if (!s.redirectFrom && s.status === g.not_matched && this.mode === "hash" && s.to.index.startsWith("/")) {
1003
- const r = s.to.index.slice(1), o = window.document.getElementById(r);
1004
- o && o.scrollIntoView({ behavior: this.scrollBehavior }), this.updateHash(`#${r}`), this.webHistory.replaceState(this.createState(s.from), "", s.from.fullPath);
1005
- }
1004
+ if (!s.redirectFrom && this.mode === "hash" && s.status !== p.success)
1005
+ if (s.status === p.not_matched) {
1006
+ if (s.to.index.startsWith("/")) {
1007
+ const r = s.to.index.slice(1), o = window.document.getElementById(r);
1008
+ o && o.scrollIntoView({ behavior: this.scrollBehavior }), this.updateHash(`#${r}`), this.webHistory.replaceState(
1009
+ this.createState(this.currentRouteLocation),
1010
+ "",
1011
+ this.currentRouteLocation.fullPath
1012
+ );
1013
+ }
1014
+ } else s.status === p.duplicated && this.webHistory.replaceState(
1015
+ this.createState(this.currentRouteLocation),
1016
+ "",
1017
+ this.currentRouteLocation.fullPath
1018
+ );
1006
1019
  });
1007
1020
  }
1008
1021
  /**
@@ -1018,7 +1031,7 @@ class mt extends p {
1018
1031
  }
1019
1032
  }
1020
1033
  }
1021
- class C extends p {
1034
+ class F extends d {
1022
1035
  constructor(i) {
1023
1036
  super(i);
1024
1037
  // 路由历史记录数组
@@ -1046,7 +1059,7 @@ class C extends p {
1046
1059
  if (s === n) return;
1047
1060
  const r = this._history[s];
1048
1061
  this._pendingGo = s, this.navigate(r).then((o) => {
1049
- o.status !== g.success && (this._pendingGo = null);
1062
+ o.status !== p.success && (this._pendingGo = null);
1050
1063
  });
1051
1064
  }
1052
1065
  /**
@@ -1087,39 +1100,39 @@ class C extends p {
1087
1100
  this._currentIndex = s, this.completeNavigation(i), this._pendingGo = null;
1088
1101
  }
1089
1102
  }
1090
- function _t(...e) {
1103
+ function Et(...e) {
1091
1104
  return e;
1092
1105
  }
1093
- function xt(e) {
1106
+ function $t(e) {
1094
1107
  return e;
1095
1108
  }
1096
- function Pt(e) {
1109
+ function Lt(e) {
1097
1110
  let t;
1098
- return !(window != null && window.location) && e.mode !== "memory" ? (console.warn("当前环境非浏览器端,强制使用内存模式路由"), e.mode = "memory", new C(e).initialize()) : (e.mode === "memory" ? t = new C(e) : t = new mt(e), t.initialize());
1111
+ return !(window != null && window.location) && e.mode !== "memory" ? (console.warn("当前环境非浏览器端,强制使用内存模式路由"), e.mode = "memory", new F(e).initialize()) : (e.mode === "memory" ? t = new F(e) : t = new xt(e), t.initialize());
1099
1112
  }
1100
- function Et() {
1101
- return p.instance;
1113
+ function Vt() {
1114
+ return d.instance;
1102
1115
  }
1103
- function vt() {
1104
- return p.instance.currentRouteLocation;
1116
+ function Ot() {
1117
+ return d.instance.currentRouteLocation;
1105
1118
  }
1106
- function bt(e) {
1107
- return e[F] = !0, e;
1119
+ function jt(e) {
1120
+ return e[U] = !0, e;
1108
1121
  }
1109
- var $, y, w, P;
1110
- const b = class b extends J {
1122
+ var E, y, w, x;
1123
+ const b = class b extends M {
1111
1124
  constructor(i) {
1112
1125
  super(i);
1113
1126
  // 自身index
1114
- x(this, y);
1127
+ _(this, y);
1115
1128
  // 当前匹配的路由配置
1116
- x(this, w);
1129
+ _(this, w);
1117
1130
  // 当前视图元素
1118
- x(this, P, Q());
1119
- const n = X(f(b, $), -1, this);
1120
- v(this, y, n + 1), Z(f(b, $), f(this, y), this), v(this, w, this.matchedRoute), f(this, w) && (f(this, P).value = p.routeView(f(this, w), this.name)), N(this.location.matched, (s, r) => {
1131
+ _(this, x, N());
1132
+ const n = tt(f(b, E), -1, this);
1133
+ v(this, y, n + 1), et(f(b, E), f(this, y), this), v(this, w, this.matchedRoute), f(this, w) && (f(this, x).value = d.routeView(f(this, w), this.name)), it(this.location.matched, (s, r) => {
1121
1134
  const o = r[this.index];
1122
- o !== f(this, w) && (v(this, w, o), f(this, P).value = o ? p.routeView(o, this.name) : void 0);
1135
+ o !== f(this, w) && (v(this, w, o), f(this, x).value = o ? d.routeView(o, this.name) : void 0);
1123
1136
  });
1124
1137
  }
1125
1138
  /**
@@ -1155,7 +1168,7 @@ const b = class b extends J {
1155
1168
  * @protected
1156
1169
  */
1157
1170
  get currentElement() {
1158
- return f(this, P).value;
1171
+ return f(this, x).value;
1159
1172
  }
1160
1173
  /**
1161
1174
  * 当前的路由位置对象
@@ -1163,7 +1176,7 @@ const b = class b extends J {
1163
1176
  * @protected
1164
1177
  */
1165
1178
  get location() {
1166
- return p.instance.currentRouteLocation;
1179
+ return d.instance.currentRouteLocation;
1167
1180
  }
1168
1181
  /**
1169
1182
  * @inheritDoc
@@ -1195,7 +1208,7 @@ const b = class b extends J {
1195
1208
  * @protected
1196
1209
  */
1197
1210
  build() {
1198
- return this.currentElement || V(tt);
1211
+ return this.currentElement || V(nt);
1199
1212
  }
1200
1213
  /**
1201
1214
  * 视图渲染完成通知路由器
@@ -1203,21 +1216,96 @@ const b = class b extends J {
1203
1216
  * @private
1204
1217
  */
1205
1218
  completeViewRender() {
1206
- this.isLastView && p.instance._completeViewRender();
1219
+ this.isLastView && d.instance._completeViewRender();
1207
1220
  }
1208
1221
  };
1209
- $ = new WeakMap(), y = new WeakMap(), w = new WeakMap(), P = new WeakMap(), x(b, $, Symbol("RouterViewCounter"));
1210
- let z = b;
1222
+ E = new WeakMap(), y = new WeakMap(), w = new WeakMap(), x = new WeakMap(), _(b, E, Symbol("RouterViewCounter"));
1223
+ let Y = b;
1224
+ class kt extends M {
1225
+ constructor(i) {
1226
+ super(i);
1227
+ /**
1228
+ * 路由目标
1229
+ *
1230
+ * 计算属性
1231
+ *
1232
+ * @protected
1233
+ */
1234
+ l(this, "target");
1235
+ /**
1236
+ * 路由目标对应的`RouteLocation`对象
1237
+ *
1238
+ * 计算属性
1239
+ *
1240
+ * @protected
1241
+ */
1242
+ l(this, "location");
1243
+ /**
1244
+ * 激活状态
1245
+ *
1246
+ * 计算属性
1247
+ *
1248
+ * @protected
1249
+ */
1250
+ l(this, "active");
1251
+ l(this, "htmlProps");
1252
+ this.target = new L(() => k(st(i.to) ? { index: i.to } : i.to)), this.location = new L(() => {
1253
+ const n = d.instance.createRouteLocation(this.target.value);
1254
+ return n.matched.length || console.trace(
1255
+ `[Vitarx.RouterLink][WARN]:索引:${this.target.value.index},未匹配到任何有效的路由线路,请检查to属性是否配置正确!`
1256
+ ), k(n);
1257
+ }), this.active = new L(() => this.location.value.fullPath === d.instance.currentRouteLocation.fullPath), this.htmlProps = new L(() => {
1258
+ const n = {
1259
+ href: this.href,
1260
+ onClick: (s) => this.navigate(s),
1261
+ children: this.children,
1262
+ style: this.props.style,
1263
+ class: this.props.class
1264
+ };
1265
+ return this.isActive && (n.active = !0), this.isDisabled && (n.disabled = !0), n;
1266
+ });
1267
+ }
1268
+ /**
1269
+ * 当前是否处于激活状态
1270
+ */
1271
+ get isActive() {
1272
+ return this.active.value && !this.isDisabled;
1273
+ }
1274
+ get isDisabled() {
1275
+ return this.props.disabled ?? !1;
1276
+ }
1277
+ /**
1278
+ * 路由目标地址
1279
+ */
1280
+ get href() {
1281
+ return this.location.value.fullPath;
1282
+ }
1283
+ /**
1284
+ * 导航到目标路由
1285
+ *
1286
+ * 该方法用于处理`a`标签的点击事件
1287
+ *
1288
+ * @param e
1289
+ */
1290
+ navigate(i) {
1291
+ i.stopPropagation(), i.preventDefault(), !this.isDisabled && d.instance.navigate(this.location.value).then();
1292
+ }
1293
+ build() {
1294
+ return V("a", this.htmlProps.value);
1295
+ }
1296
+ }
1211
1297
  export {
1212
- C as MemoryRouter,
1213
- g as NavigateStatus,
1214
- p as Router,
1215
- z as RouterView,
1216
- mt as WebHistoryRouter,
1217
- Pt as createRouter,
1218
- xt as defineRoute,
1219
- _t as defineRoutes,
1220
- bt as lazy,
1221
- vt as useRoute,
1222
- Et as useRouter
1298
+ F as MemoryRouter,
1299
+ p as NavigateStatus,
1300
+ d as Router,
1301
+ kt as RouterLink,
1302
+ Y as RouterView,
1303
+ xt as WebHistoryRouter,
1304
+ Lt as createRouter,
1305
+ $t as defineRoute,
1306
+ Et as defineRoutes,
1307
+ bt as generateRouteIndex,
1308
+ jt as lazy,
1309
+ Ot as useRoute,
1310
+ Vt as useRouter
1223
1311
  };
@@ -0,0 +1,80 @@
1
+ import { Computed, Element, WebRuntimeDom, Widget } from 'vitarx';
2
+ import { RouteIndex, RouteLocation, RouteTarget } from '../router/index.js';
3
+ export interface RouterLinkProps {
4
+ /**
5
+ * 要跳转的目标
6
+ *
7
+ * 可以是路由目标对象,也可以是路由索引
8
+ */
9
+ to: RouteTarget | RouteIndex;
10
+ /**
11
+ * 子节点插槽
12
+ */
13
+ children: Element | Element[] | string;
14
+ /**
15
+ * a 标签的style属性
16
+ */
17
+ style?: WebRuntimeDom.HTMLStyleProperties;
18
+ /**
19
+ * a 标签的class属性
20
+ */
21
+ class?: WebRuntimeDom.HTMLClassProperties;
22
+ /**
23
+ * 是否禁用
24
+ *
25
+ * @default false
26
+ */
27
+ disabled?: boolean;
28
+ }
29
+ /**
30
+ * # 路由跳转小部件
31
+ *
32
+ * 它只是简单的实现了一个a标签,点击后跳转到目标路由,
33
+ * 如果有更高级的定制需求,往往你可以项目中自行编写一个小部件来实现任何你想要的效果。
34
+ */
35
+ export declare class RouterLink extends Widget<RouterLinkProps> {
36
+ /**
37
+ * 路由目标
38
+ *
39
+ * 计算属性
40
+ *
41
+ * @protected
42
+ */
43
+ protected target: Computed<RouteTarget>;
44
+ /**
45
+ * 路由目标对应的`RouteLocation`对象
46
+ *
47
+ * 计算属性
48
+ *
49
+ * @protected
50
+ */
51
+ protected location: Computed<RouteLocation>;
52
+ /**
53
+ * 激活状态
54
+ *
55
+ * 计算属性
56
+ *
57
+ * @protected
58
+ */
59
+ protected active: Computed<boolean>;
60
+ protected htmlProps: Computed<WebRuntimeDom.HtmlProperties<HTMLAnchorElement>>;
61
+ constructor(props: RouterLinkProps);
62
+ /**
63
+ * 当前是否处于激活状态
64
+ */
65
+ get isActive(): boolean;
66
+ get isDisabled(): boolean;
67
+ /**
68
+ * 路由目标地址
69
+ */
70
+ get href(): string;
71
+ /**
72
+ * 导航到目标路由
73
+ *
74
+ * 该方法用于处理`a`标签的点击事件
75
+ *
76
+ * @param e
77
+ */
78
+ protected navigate(e: MouseEvent): void;
79
+ protected build(): Element;
80
+ }
@@ -1 +1,2 @@
1
1
  export * from './RouterView.js';
2
+ export * from './RouterLink.js';
package/package.json CHANGED
@@ -1,14 +1,15 @@
1
1
  {
2
2
  "name": "vitarx-router",
3
- "version": "0.0.1",
3
+ "version": "1.0.0-beta.2",
4
4
  "type": "module",
5
5
  "main": "dist/vitarx-router.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "scripts": {
8
8
  "dev": "vite --force",
9
- "build": "rimraf dist && tsc --p tsconfig-build.json && vite build",
9
+ "build:lib": "rimraf dist && tsc --p tsconfig-lib.json && vite --config vite.config.lib.ts build",
10
+ "build": "rimraf dist-web && vite build",
10
11
  "preview": "vite preview",
11
- "prepublishOnly": "npm run build",
12
+ "prepublishOnly": "npm run build:lib",
12
13
  "push": "npm publish --access=public"
13
14
  },
14
15
  "peerDependencies": {
@@ -18,7 +19,7 @@
18
19
  "@types/node": "^22.10.0",
19
20
  "prettier": "^3.3.1",
20
21
  "typescript": "^5.2.2",
21
- "vite": "^5.2.0",
22
+ "vite": "^6.0.5",
22
23
  "vite-plugin-dts": "^4.3.0",
23
24
  "vite-plugin-vitarx": "^1.0.0-beta.13"
24
25
  },