wevu 6.7.6 → 6.8.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.
package/README.md CHANGED
@@ -14,7 +14,7 @@ Vue 3 风格的小程序运行时,复用同款响应式与调度器,通过
14
14
  ## 安装
15
15
 
16
16
  ```bash
17
- pnpm add wevu
17
+ pnpm add -D wevu
18
18
  # 或 npm/yarn/pnpm dlx 按需安装
19
19
  ```
20
20
 
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { A as track, C as effect, D as onScopeDispose, E as getCurrentScope, M as triggerEffects, N as nextTick, O as startBatch, P as queueJob, S as batch, T as endBatch, _ as ReactiveFlags, a as toValue, b as addMutationRecorder, c as isRaw, d as reactive, f as isShallowReactive, g as touchReactive, h as prelinkReactiveTree, i as ref, j as trigger, k as stop, l as isReactive, m as clearPatchIndices, n as isRef, o as unref, p as shallowReactive, r as markAsRef, s as getReactiveVersion, t as customRef, u as markRaw, v as isObject$1, w as effectScope, x as removeMutationRecorder, y as toRaw } from "./ref-BjmD-qct.mjs";
2
2
  import { i as computed, n as defineStore, r as createStore, t as storeToRefs } from "./store-Ct-o7qtH.mjs";
3
- import { A as getCurrentInstance, C as onTabItemTap, D as assertInSetup, E as onUnload, F as getMiniProgramGlobalObject, I as getScopedSlotHostGlobalObject, L as readonly, M as pushHook, N as setCurrentInstance, O as callHookList, P as setCurrentSetupContext, S as onShow, T as onUnhandledRejection, _ as onResize, a as onDetached, b as onShareAppMessage, c as onLaunch, d as onMoved, f as onPageNotFound, g as onReady, h as onReachBottom, i as onAttached, j as getCurrentSetupContext, k as callHookReturn, l as onLoad, m as onPullDownRefresh, n as useNativeRouter, o as onError, p as onPageScroll, r as onAddToFavorites, s as onHide, t as useNativePageRouter, u as onMemoryWarning, v as onRouteDone, w as onThemeChange, x as onShareTimeline, y as onSaveExitState } from "./router-CcoGUezU.mjs";
3
+ import { A as onUnload, B as getScopedSlotHostGlobalObject, C as onSaveExitState, D as onTabItemTap, E as onShow, F as getCurrentSetupContext, I as pushHook, L as setCurrentInstance, M as callHookList, N as callHookReturn, O as onThemeChange, P as getCurrentInstance, R as setCurrentSetupContext, S as onRouteDone, T as onShareTimeline, V as readonly, _ as onPageScroll, a as provide, b as onReady, c as onAttached, d as onHide, f as onLaunch, g as onPageNotFound, h as onMoved, i as injectGlobal, j as assertInSetup, k as onUnhandledRejection, l as onDetached, m as onMemoryWarning, n as useNativeRouter, o as provideGlobal, p as onLoad, r as inject, s as onAddToFavorites, t as useNativePageRouter, u as onError, v as onPullDownRefresh, w as onShareAppMessage, x as onResize, y as onReachBottom, z as getMiniProgramGlobalObject } from "./router-BoEmd9rt.mjs";
4
4
  //#region src/reactivity/shallowRef.ts
5
5
  /**
6
6
  * 创建一个“浅层” ref:它只在 .value 被整体替换时触发依赖,不会对内部对象做深层响应式处理。
@@ -4651,87 +4651,6 @@ function usePageScrollThrottle(handler, options = {}) {
4651
4651
  return stop;
4652
4652
  }
4653
4653
  //#endregion
4654
- //#region src/runtime/provide.ts
4655
- const PROVIDE_SCOPE_KEY = Symbol("wevu.provideScope");
4656
- const __wevuGlobalProvideStore = /* @__PURE__ */ new Map();
4657
- /**
4658
- * 在组件上下文中向后代注入值(与 Vue 3 行为兼容),若没有当前实例则回落到全局存储。
4659
- *
4660
- * @param key 注入键,可为字符串、Symbol 或对象
4661
- * @param value 提供的值
4662
- *
4663
- * @example
4664
- * ```ts
4665
- * defineComponent({
4666
- * setup() {
4667
- * provide(TOKEN_KEY, { data: 'value' })
4668
- * }
4669
- * })
4670
- * ```
4671
- */
4672
- function provide(key, value) {
4673
- const instance = getCurrentInstance();
4674
- if (instance) {
4675
- let scope = instance[PROVIDE_SCOPE_KEY];
4676
- if (!scope) {
4677
- scope = /* @__PURE__ */ new Map();
4678
- instance[PROVIDE_SCOPE_KEY] = scope;
4679
- }
4680
- scope.set(key, value);
4681
- } else __wevuGlobalProvideStore.set(key, value);
4682
- }
4683
- /**
4684
- * 从祖先组件(或全局存储)读取提供的值。
4685
- *
4686
- * @param key 注入键,需与 provide 使用的键保持一致
4687
- * @param defaultValue 未找到提供者时的默认值
4688
- * @returns 匹配到的值或默认值
4689
- *
4690
- * @example
4691
- * ```ts
4692
- * defineComponent({
4693
- * setup() {
4694
- * const data = inject(TOKEN_KEY)
4695
- * const value = inject('key', 'default')
4696
- * }
4697
- * })
4698
- * ```
4699
- */
4700
- function inject(key, defaultValue) {
4701
- const instance = getCurrentInstance();
4702
- if (instance) {
4703
- let current = instance;
4704
- while (current) {
4705
- const scope = current[PROVIDE_SCOPE_KEY];
4706
- if (scope && scope.has(key)) return scope.get(key);
4707
- current = null;
4708
- }
4709
- }
4710
- if (__wevuGlobalProvideStore.has(key)) return __wevuGlobalProvideStore.get(key);
4711
- if (arguments.length >= 2) return defaultValue;
4712
- throw new Error("wevu.inject:未找到对应 key 的值");
4713
- }
4714
- /**
4715
- * 全局注入值,适用于历史兼容场景。
4716
- *
4717
- * @deprecated 已弃用,仅用于兼容/过渡。推荐优先使用 `provide()`,
4718
- * 在无实例上下文时 `provide()` 会自动回落到全局存储。
4719
- */
4720
- function provideGlobal(key, value) {
4721
- __wevuGlobalProvideStore.set(key, value);
4722
- }
4723
- /**
4724
- * 从全局存储读取值,适用于历史兼容场景。
4725
- *
4726
- * @deprecated 已弃用,仅用于兼容/过渡。推荐优先使用 `inject()`,
4727
- * 在无实例上下文时 `inject()` 会自动从全局存储读取。
4728
- */
4729
- function injectGlobal(key, defaultValue) {
4730
- if (__wevuGlobalProvideStore.has(key)) return __wevuGlobalProvideStore.get(key);
4731
- if (arguments.length >= 2) return defaultValue;
4732
- throw new Error(`injectGlobal():未找到对应 key 的 provider:${String(key)}`);
4733
- }
4734
- //#endregion
4735
4654
  //#region src/runtime/template.ts
4736
4655
  const hyphenateRE = /\B([A-Z])/g;
4737
4656
  function hyphenate(value) {
@@ -262,6 +262,87 @@ function onAddToFavorites(handler) {
262
262
  ensureSinglePageHookOnInstance(instance, "onAddToFavorites");
263
263
  }
264
264
  //#endregion
265
+ //#region src/runtime/provide.ts
266
+ const PROVIDE_SCOPE_KEY = Symbol("wevu.provideScope");
267
+ const __wevuGlobalProvideStore = /* @__PURE__ */ new Map();
268
+ /**
269
+ * 在组件上下文中向后代注入值(与 Vue 3 行为兼容),若没有当前实例则回落到全局存储。
270
+ *
271
+ * @param key 注入键,可为字符串、Symbol 或对象
272
+ * @param value 提供的值
273
+ *
274
+ * @example
275
+ * ```ts
276
+ * defineComponent({
277
+ * setup() {
278
+ * provide(TOKEN_KEY, { data: 'value' })
279
+ * }
280
+ * })
281
+ * ```
282
+ */
283
+ function provide(key, value) {
284
+ const instance = getCurrentInstance();
285
+ if (instance) {
286
+ let scope = instance[PROVIDE_SCOPE_KEY];
287
+ if (!scope) {
288
+ scope = /* @__PURE__ */ new Map();
289
+ instance[PROVIDE_SCOPE_KEY] = scope;
290
+ }
291
+ scope.set(key, value);
292
+ } else __wevuGlobalProvideStore.set(key, value);
293
+ }
294
+ /**
295
+ * 从祖先组件(或全局存储)读取提供的值。
296
+ *
297
+ * @param key 注入键,需与 provide 使用的键保持一致
298
+ * @param defaultValue 未找到提供者时的默认值
299
+ * @returns 匹配到的值或默认值
300
+ *
301
+ * @example
302
+ * ```ts
303
+ * defineComponent({
304
+ * setup() {
305
+ * const data = inject(TOKEN_KEY)
306
+ * const value = inject('key', 'default')
307
+ * }
308
+ * })
309
+ * ```
310
+ */
311
+ function inject(key, defaultValue) {
312
+ const instance = getCurrentInstance();
313
+ if (instance) {
314
+ let current = instance;
315
+ while (current) {
316
+ const scope = current[PROVIDE_SCOPE_KEY];
317
+ if (scope && scope.has(key)) return scope.get(key);
318
+ current = null;
319
+ }
320
+ }
321
+ if (__wevuGlobalProvideStore.has(key)) return __wevuGlobalProvideStore.get(key);
322
+ if (arguments.length >= 2) return defaultValue;
323
+ throw new Error("wevu.inject:未找到对应 key 的值");
324
+ }
325
+ /**
326
+ * 全局注入值,适用于历史兼容场景。
327
+ *
328
+ * @deprecated 已弃用,仅用于兼容/过渡。推荐优先使用 `provide()`,
329
+ * 在无实例上下文时 `provide()` 会自动回落到全局存储。
330
+ */
331
+ function provideGlobal(key, value) {
332
+ __wevuGlobalProvideStore.set(key, value);
333
+ }
334
+ /**
335
+ * 从全局存储读取值,适用于历史兼容场景。
336
+ *
337
+ * @deprecated 已弃用,仅用于兼容/过渡。推荐优先使用 `inject()`,
338
+ * 在无实例上下文时 `inject()` 会自动从全局存储读取。
339
+ */
340
+ function injectGlobal(key, defaultValue) {
341
+ if (__wevuGlobalProvideStore.has(key)) return __wevuGlobalProvideStore.get(key);
342
+ if (arguments.length >= 2) return defaultValue;
343
+ throw new Error(`injectGlobal():未找到对应 key 的 provider:${String(key)}`);
344
+ }
345
+ //#endregion
265
346
  //#region src/runtime/vueCompat/router.ts
266
347
  const RUNTIME_ROUTER_METHODS = [
267
348
  "switchTab",
@@ -326,4 +407,4 @@ function useNativePageRouter() {
326
407
  return useRuntimeRouterByAccessor("pageRouter", "router", "useNativePageRouter");
327
408
  }
328
409
  //#endregion
329
- export { getCurrentInstance as A, onTabItemTap as C, assertInSetup as D, onUnload as E, getMiniProgramGlobalObject as F, getScopedSlotHostGlobalObject as I, readonly as L, pushHook as M, setCurrentInstance as N, callHookList as O, setCurrentSetupContext as P, onShow as S, onUnhandledRejection as T, onResize as _, onDetached as a, onShareAppMessage as b, onLaunch as c, onMoved as d, onPageNotFound as f, onReady as g, onReachBottom as h, onAttached as i, getCurrentSetupContext as j, callHookReturn as k, onLoad as l, onPullDownRefresh as m, useNativeRouter as n, onError as o, onPageScroll as p, onAddToFavorites as r, onHide as s, useNativePageRouter as t, onMemoryWarning as u, onRouteDone as v, onThemeChange as w, onShareTimeline as x, onSaveExitState as y };
410
+ export { onUnload as A, getScopedSlotHostGlobalObject as B, onSaveExitState as C, onTabItemTap as D, onShow as E, getCurrentSetupContext as F, pushHook as I, setCurrentInstance as L, callHookList as M, callHookReturn as N, onThemeChange as O, getCurrentInstance as P, setCurrentSetupContext as R, onRouteDone as S, onShareTimeline as T, readonly as V, onPageScroll as _, provide as a, onReady as b, onAttached as c, onHide as d, onLaunch as f, onPageNotFound as g, onMoved as h, injectGlobal as i, assertInSetup as j, onUnhandledRejection as k, onDetached as l, onMemoryWarning as m, useNativeRouter as n, provideGlobal as o, onLoad as p, inject as r, onAddToFavorites as s, useNativePageRouter as t, onError as u, onPullDownRefresh as v, onShareAppMessage as w, onResize as x, onReachBottom as y, getMiniProgramGlobalObject as z };
package/dist/router.d.mts CHANGED
@@ -27,6 +27,15 @@ interface NamedRouteRecord {
27
27
  name: string;
28
28
  path: string;
29
29
  }
30
+ interface RouteRecordInput {
31
+ name?: string;
32
+ path: string;
33
+ meta?: RouteMeta;
34
+ alias?: string | readonly string[];
35
+ children?: readonly RouteRecordInput[];
36
+ beforeEnter?: NavigationGuard | readonly NavigationGuard[];
37
+ redirect?: RouteRecordRedirect;
38
+ }
30
39
  type NamedRoutes = Readonly<Record<string, string>> | readonly RouteRecordRaw[];
31
40
  type RouteLocationRaw = string | {
32
41
  path?: string;
@@ -68,12 +77,8 @@ interface NavigationRedirect {
68
77
  replace?: boolean;
69
78
  }
70
79
  type RouteRecordRedirect = RouteLocationRaw | NavigationRedirect | ((to: RouteLocationNormalizedLoaded, from: RouteLocationNormalizedLoaded) => RouteLocationRaw | NavigationRedirect | Promise<RouteLocationRaw | NavigationRedirect>);
71
- interface RouteRecordRaw extends NamedRouteRecord {
72
- meta?: RouteMeta;
73
- alias?: string | readonly string[];
80
+ interface RouteRecordRaw extends Omit<RouteRecordInput, 'name' | 'children'>, NamedRouteRecord {
74
81
  children?: readonly RouteRecordRaw[];
75
- beforeEnter?: NavigationGuard | readonly NavigationGuard[];
76
- redirect?: RouteRecordRedirect;
77
82
  }
78
83
  interface RouteRecordMatched {
79
84
  name: string;
@@ -121,7 +126,7 @@ interface UseRouterOptions {
121
126
  /**
122
127
  * Vue Router 对齐入口:推荐使用 `routes`
123
128
  */
124
- routes?: readonly RouteRecordRaw[];
129
+ routes?: readonly RouteRecordInput[];
125
130
  /**
126
131
  * 兼容入口:支持对象 map 或路由记录数组
127
132
  */
@@ -165,6 +170,12 @@ interface AddRoute {
165
170
  (parentName: string, route: RouteRecordRaw): () => void;
166
171
  }
167
172
  //#endregion
173
+ //#region src/router/createRouter.d.ts
174
+ /**
175
+ * @description 创建高阶路由导航器(对齐 Vue Router 的 createRouter 心智)
176
+ */
177
+ declare function createRouter(options?: UseRouterOptions): RouterNavigation;
178
+ //#endregion
168
179
  //#region src/router/navigationCore.d.ts
169
180
  declare function createNavigationFailure(type: NavigationFailureTypeValue, to?: RouteLocationNormalizedLoaded, from?: RouteLocationNormalizedLoaded, cause?: unknown): NavigationFailure;
170
181
  declare function isNavigationFailure(error: unknown, type?: NavigationFailureTypeValue): error is NavigationFailure;
@@ -185,8 +196,8 @@ declare function useNativePageRouter(): SetupContextRouter;
185
196
  //#endregion
186
197
  //#region src/router/useRouter.d.ts
187
198
  /**
188
- * @description 获取高阶路由导航器(对齐 Vue Router 心智)
199
+ * @description 获取当前已创建的路由实例。
189
200
  */
190
- declare function useRouter(options?: UseRouterOptions): RouterNavigation;
201
+ declare function useRouter(): RouterNavigation;
191
202
  //#endregion
192
- export { type AddRoute, type LocationQuery, type LocationQueryRaw, type LocationQueryValue, type LocationQueryValueRaw, type NamedRouteRecord, type NamedRoutes, type NavigationAfterEach, type NavigationAfterEachContext, type NavigationErrorContext, type NavigationErrorHandler, type NavigationFailure, NavigationFailureType, type NavigationFailureTypeValue, type NavigationGuard, type NavigationGuardContext, type NavigationGuardResult, type NavigationMode, type NavigationRedirect, type RouteLocationNormalizedLoaded, type RouteLocationRaw, type RouteLocationRedirectedFrom, type RouteMeta, type RouteParamValue, type RouteParamValueRaw, type RouteParams, type RouteParamsMode, type RouteParamsRaw, type RouteQueryParser, type RouteQueryStringifier, type RouteRecordMatched, type RouteRecordRaw, type RouteRecordRedirect, type RouterNavigateToOption, type RouterNavigation, type RouterReLaunchOption, type RouterRedirectToOption, type RouterSwitchTabOption, type SetupContextRouter, type TypedRouterTabBarUrl, type TypedRouterUrl, type UseRouterOptions, type WevuTypedRouterRouteMap, createNavigationFailure, isNavigationFailure, parseQuery, resolveRouteLocation, stringifyQuery, useNativePageRouter, useNativeRouter, useRoute, useRouter };
203
+ export { type AddRoute, type LocationQuery, type LocationQueryRaw, type LocationQueryValue, type LocationQueryValueRaw, type NamedRouteRecord, type NamedRoutes, type NavigationAfterEach, type NavigationAfterEachContext, type NavigationErrorContext, type NavigationErrorHandler, type NavigationFailure, NavigationFailureType, type NavigationFailureTypeValue, type NavigationGuard, type NavigationGuardContext, type NavigationGuardResult, type NavigationMode, type NavigationRedirect, type RouteLocationNormalizedLoaded, type RouteLocationRaw, type RouteLocationRedirectedFrom, type RouteMeta, type RouteParamValue, type RouteParamValueRaw, type RouteParams, type RouteParamsMode, type RouteParamsRaw, type RouteQueryParser, type RouteQueryStringifier, type RouteRecordInput, type RouteRecordMatched, type RouteRecordRaw, type RouteRecordRedirect, type RouterNavigateToOption, type RouterNavigation, type RouterReLaunchOption, type RouterRedirectToOption, type RouterSwitchTabOption, type SetupContextRouter, type TypedRouterTabBarUrl, type TypedRouterUrl, type UseRouterOptions, type WevuTypedRouterRouteMap, createNavigationFailure, createRouter, isNavigationFailure, parseQuery, resolveRouteLocation, stringifyQuery, useNativePageRouter, useNativeRouter, useRoute, useRouter };
package/dist/router.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { d as reactive } from "./ref-BjmD-qct.mjs";
2
- import { L as readonly, S as onShow, j as getCurrentSetupContext, l as onLoad, n as useNativeRouter$1, t as useNativePageRouter$1, v as onRouteDone } from "./router-CcoGUezU.mjs";
2
+ import { E as onShow, F as getCurrentSetupContext, S as onRouteDone, V as readonly, i as injectGlobal, n as useNativeRouter$1, o as provideGlobal, p as onLoad, t as useNativePageRouter$1 } from "./router-BoEmd9rt.mjs";
3
3
  //#region src/routerInternal/path.ts
4
4
  function normalizePathSegments(path) {
5
5
  const segments = [];
@@ -283,7 +283,7 @@ function resolveNamedRouteLocation(to, lookup, paramsMode) {
283
283
  if (typeof routeName !== "string" || !routeName) return to;
284
284
  if (to.path !== void 0 || to.fullPath !== void 0) return to;
285
285
  const routeRecord = lookup.recordByName.get(routeName);
286
- if (!routeRecord) throw new Error(`Named route "${routeName}" is not defined in useRouter({ routes | namedRoutes })`);
286
+ if (!routeRecord) throw new Error(`Named route "${routeName}" is not defined in createRouter({ routes | namedRoutes })`);
287
287
  const params = to.params ? normalizeRouteParams(to.params) : {};
288
288
  const resolvedResult = resolveNamedRoutePath(routeRecord.path, params, routeName);
289
289
  if (paramsMode === "strict") assertNoUnexpectedNamedRouteParams(params, resolvedResult.consumedKeys, routeName);
@@ -466,7 +466,7 @@ function warnDuplicateRouteEntries(routeEntries) {
466
466
  const duplicateMessages = [];
467
467
  for (const routeEntry of routeEntries) {
468
468
  var _routeEntry$source;
469
- const routeName = routeEntry.route.name.trim();
469
+ const routeName = typeof routeEntry.route.name === "string" ? routeEntry.route.name.trim() : "";
470
470
  if (!routeName) continue;
471
471
  const currentSource = (_routeEntry$source = routeEntry.source) !== null && _routeEntry$source !== void 0 ? _routeEntry$source : "namedRoutes";
472
472
  const currentPath = formatRoutePathForWarning(routeEntry.route.path);
@@ -487,11 +487,16 @@ function normalizeBeforeEnterGuards(beforeEnter) {
487
487
  if (Array.isArray(beforeEnter)) return beforeEnter;
488
488
  return [beforeEnter];
489
489
  }
490
- function normalizeRouteRecordRaw(route, parentName) {
491
- const routeName = route.name.trim();
492
- if (!routeName) return;
490
+ function resolveRouteRecordName(route, normalizedPath, source = "namedRoutes") {
491
+ if (typeof route.name === "string" && route.name.trim()) return route.name.trim();
492
+ if (source === "routes") return normalizedPath || "/";
493
+ return "";
494
+ }
495
+ function normalizeRouteRecordRaw(route, parentName, source = "namedRoutes") {
493
496
  const normalizedPath = resolvePath(route.path, "");
494
- if (!normalizedPath) return;
497
+ if (!normalizedPath && route.path !== "/") return;
498
+ const routeName = resolveRouteRecordName(route, normalizedPath, source);
499
+ if (!routeName) return;
495
500
  return {
496
501
  name: routeName,
497
502
  path: normalizedPath,
@@ -571,16 +576,16 @@ function flattenNamedRouteRecords(records, parentPath, parentName, parentAliasPa
571
576
  warnRouteConfig(`ignored route record at ${routeConfigPath}: detected circular children reference`);
572
577
  continue;
573
578
  }
574
- const routeName = typeof (record === null || record === void 0 ? void 0 : record.name) === "string" ? record.name.trim() : "";
575
- if (!routeName) {
576
- warnRouteConfig(`ignored route record at ${routeConfigPath}: route name is required`);
577
- continue;
578
- }
579
579
  if (typeof record.path !== "string" || !record.path) {
580
- warnRouteConfig(`ignored route record "${routeName}" at ${routeConfigPath}: route path is required`);
580
+ warnRouteConfig(`ignored route record "${typeof (record === null || record === void 0 ? void 0 : record.name) === "string" ? record.name.trim() : ""}" at ${routeConfigPath}: route path is required`);
581
581
  continue;
582
582
  }
583
583
  const normalizedPath = normalizeNestedRoutePath(record.path, parentPath);
584
+ const routeName = resolveRouteRecordName(record, normalizedPath, source);
585
+ if (!routeName) {
586
+ warnRouteConfig(`ignored route record at ${routeConfigPath}: route name is required`);
587
+ continue;
588
+ }
584
589
  const normalizedDirectAliasPaths = [];
585
590
  const directAliasByNormalizedPath = /* @__PURE__ */ new Map();
586
591
  for (const rawAliasPath of normalizeAliasInputList(record.alias)) {
@@ -630,7 +635,7 @@ function createNamedRouteNameByStaticPath(recordByName) {
630
635
  function createNamedRouteLookup(routeEntries) {
631
636
  const recordByName = /* @__PURE__ */ new Map();
632
637
  for (const routeRecord of routeEntries) {
633
- const normalizedRecord = normalizeRouteRecordRaw(routeRecord.route, routeRecord.parentName);
638
+ const normalizedRecord = normalizeRouteRecordRaw(routeRecord.route, routeRecord.parentName, routeRecord.source);
634
639
  if (!normalizedRecord) continue;
635
640
  recordByName.set(normalizedRecord.name, normalizedRecord);
636
641
  }
@@ -760,6 +765,18 @@ function hasLocationQuery(query) {
760
765
  return Object.keys(query).length > 0;
761
766
  }
762
767
  //#endregion
768
+ //#region src/router/instance.ts
769
+ const ROUTER_INSTANCE_KEY = Symbol("wevu.router.instance");
770
+ let activeRouter;
771
+ function setActiveRouter(router) {
772
+ activeRouter = router;
773
+ provideGlobal(ROUTER_INSTANCE_KEY, router);
774
+ }
775
+ function getActiveRouter() {
776
+ var _activeRouter;
777
+ return (_activeRouter = activeRouter) !== null && _activeRouter !== void 0 ? _activeRouter : injectGlobal(ROUTER_INSTANCE_KEY, void 0);
778
+ }
779
+ //#endregion
763
780
  //#region src/router/types.ts
764
781
  const NavigationFailureType = {
765
782
  unknown: 1,
@@ -902,69 +919,6 @@ function shouldEmitNavigationError(failure) {
902
919
  return false;
903
920
  }
904
921
  //#endregion
905
- //#region src/router/resolve.ts
906
- const DEFAULT_ROUTE_RESOLVE_CODEC = {
907
- parseQuery,
908
- stringifyQuery
909
- };
910
- function resolveRouteLocation(to, currentPath = "", codec = DEFAULT_ROUTE_RESOLVE_CODEC) {
911
- var _ref, _to$path, _parsedFromFullPath$q, _to$hash;
912
- if (typeof to === "string") {
913
- const parsed = parsePathInput(to, codec);
914
- return createRouteLocation(resolvePath(parsed.path, currentPath), parsed.query, parsed.hash, void 0, {}, codec.stringifyQuery);
915
- }
916
- const parsedFromFullPath = typeof to.fullPath === "string" ? parsePathInput(to.fullPath, codec) : void 0;
917
- return createRouteLocation(resolvePath((_ref = (_to$path = to.path) !== null && _to$path !== void 0 ? _to$path : parsedFromFullPath === null || parsedFromFullPath === void 0 ? void 0 : parsedFromFullPath.path) !== null && _ref !== void 0 ? _ref : currentPath, currentPath), to.query ? normalizeQuery(to.query) : (_parsedFromFullPath$q = parsedFromFullPath === null || parsedFromFullPath === void 0 ? void 0 : parsedFromFullPath.query) !== null && _parsedFromFullPath$q !== void 0 ? _parsedFromFullPath$q : {}, normalizeHash((_to$hash = to.hash) !== null && _to$hash !== void 0 ? _to$hash : parsedFromFullPath === null || parsedFromFullPath === void 0 ? void 0 : parsedFromFullPath.hash), typeof to.name === "string" ? to.name : void 0, to.params ? normalizeRouteParams(to.params) : {}, codec.stringifyQuery);
918
- }
919
- //#endregion
920
- //#region src/router/useRoute.ts
921
- function useRoute() {
922
- if (!getCurrentSetupContext()) throw new Error("useRoute() 必须在 setup() 的同步阶段调用");
923
- const currentRoute = resolveCurrentRoute();
924
- const routeState = reactive({
925
- path: currentRoute.path,
926
- fullPath: currentRoute.fullPath,
927
- query: currentRoute.query,
928
- hash: currentRoute.hash,
929
- params: currentRoute.params,
930
- name: currentRoute.name
931
- });
932
- if (currentRoute.meta !== void 0) routeState.meta = currentRoute.meta;
933
- function syncRoute(queryOverride) {
934
- const nextRoute = resolveCurrentRoute(queryOverride);
935
- routeState.path = nextRoute.path;
936
- routeState.fullPath = nextRoute.fullPath;
937
- routeState.query = nextRoute.query;
938
- routeState.hash = nextRoute.hash;
939
- if (nextRoute.meta === void 0) delete routeState.meta;
940
- else routeState.meta = nextRoute.meta;
941
- routeState.params = nextRoute.params;
942
- routeState.name = nextRoute.name;
943
- }
944
- onLoad((query) => {
945
- syncRoute(query);
946
- });
947
- onShow(() => {
948
- syncRoute();
949
- });
950
- onRouteDone(() => {
951
- syncRoute();
952
- });
953
- return readonly(routeState);
954
- }
955
- /**
956
- * @description 获取当前组件路径语义的原生 Router
957
- */
958
- function useNativeRouter() {
959
- return useNativeRouter$1();
960
- }
961
- /**
962
- * @description 获取当前页面路径语义的原生 Page Router
963
- */
964
- function useNativePageRouter() {
965
- return useNativePageRouter$1();
966
- }
967
- //#endregion
968
922
  //#region src/router/navigationResult.ts
969
923
  function createNavigationRunResult(mode, from, to, failure) {
970
924
  return {
@@ -1231,6 +1185,21 @@ function createNavigationApi(options) {
1231
1185
  };
1232
1186
  }
1233
1187
  //#endregion
1188
+ //#region src/router/resolve.ts
1189
+ const DEFAULT_ROUTE_RESOLVE_CODEC = {
1190
+ parseQuery,
1191
+ stringifyQuery
1192
+ };
1193
+ function resolveRouteLocation(to, currentPath = "", codec = DEFAULT_ROUTE_RESOLVE_CODEC) {
1194
+ var _ref, _to$path, _parsedFromFullPath$q, _to$hash;
1195
+ if (typeof to === "string") {
1196
+ const parsed = parsePathInput(to, codec);
1197
+ return createRouteLocation(resolvePath(parsed.path, currentPath), parsed.query, parsed.hash, void 0, {}, codec.stringifyQuery);
1198
+ }
1199
+ const parsedFromFullPath = typeof to.fullPath === "string" ? parsePathInput(to.fullPath, codec) : void 0;
1200
+ return createRouteLocation(resolvePath((_ref = (_to$path = to.path) !== null && _to$path !== void 0 ? _to$path : parsedFromFullPath === null || parsedFromFullPath === void 0 ? void 0 : parsedFromFullPath.path) !== null && _ref !== void 0 ? _ref : currentPath, currentPath), to.query ? normalizeQuery(to.query) : (_parsedFromFullPath$q = parsedFromFullPath === null || parsedFromFullPath === void 0 ? void 0 : parsedFromFullPath.query) !== null && _parsedFromFullPath$q !== void 0 ? _parsedFromFullPath$q : {}, normalizeHash((_to$hash = to.hash) !== null && _to$hash !== void 0 ? _to$hash : parsedFromFullPath === null || parsedFromFullPath === void 0 ? void 0 : parsedFromFullPath.hash), typeof to.name === "string" ? to.name : void 0, to.params ? normalizeRouteParams(to.params) : {}, codec.stringifyQuery);
1201
+ }
1202
+ //#endregion
1234
1203
  //#region src/router/routeRegistry.ts
1235
1204
  function normalizeRouteRecordForOutput(record) {
1236
1205
  const normalizedRoute = {
@@ -1254,7 +1223,7 @@ function createRouteRegistry(namedRouteLookup) {
1254
1223
  assertValidAddRouteInput(route);
1255
1224
  const parentRouteName = typeof parentNameOrRoute === "string" ? parentNameOrRoute : void 0;
1256
1225
  const parentRouteRecord = parentRouteName ? namedRouteLookup.recordByName.get(parentRouteName) : void 0;
1257
- if (parentRouteName && !parentRouteRecord) throw new Error(`Parent route "${parentRouteName}" is not defined in useRouter({ routes | namedRoutes })`);
1226
+ if (parentRouteName && !parentRouteRecord) throw new Error(`Parent route "${parentRouteName}" is not defined in createRouter({ routes | namedRoutes })`);
1258
1227
  const routeRecords = flattenNamedRouteRecords([route], parentRouteRecord === null || parentRouteRecord === void 0 ? void 0 : parentRouteRecord.path, parentRouteName, parentRouteRecord === null || parentRouteRecord === void 0 ? void 0 : parentRouteRecord.aliasPaths, void 0, "addRoute");
1259
1228
  if (routeRecords.length === 0) throw new Error("Route name and path are required when adding a named route");
1260
1229
  const addedRoutes = [];
@@ -1300,11 +1269,59 @@ function createRouteRegistry(namedRouteLookup) {
1300
1269
  };
1301
1270
  }
1302
1271
  //#endregion
1303
- //#region src/router/useRouter.ts
1272
+ //#region src/router/useRoute.ts
1273
+ function useRoute() {
1274
+ if (!getCurrentSetupContext()) throw new Error("useRoute() 必须在 setup() 的同步阶段调用");
1275
+ const currentRoute = resolveCurrentRoute();
1276
+ const routeState = reactive({
1277
+ path: currentRoute.path,
1278
+ fullPath: currentRoute.fullPath,
1279
+ query: currentRoute.query,
1280
+ hash: currentRoute.hash,
1281
+ params: currentRoute.params,
1282
+ name: currentRoute.name
1283
+ });
1284
+ if (currentRoute.meta !== void 0) routeState.meta = currentRoute.meta;
1285
+ function syncRoute(queryOverride) {
1286
+ const nextRoute = resolveCurrentRoute(queryOverride);
1287
+ routeState.path = nextRoute.path;
1288
+ routeState.fullPath = nextRoute.fullPath;
1289
+ routeState.query = nextRoute.query;
1290
+ routeState.hash = nextRoute.hash;
1291
+ if (nextRoute.meta === void 0) delete routeState.meta;
1292
+ else routeState.meta = nextRoute.meta;
1293
+ routeState.params = nextRoute.params;
1294
+ routeState.name = nextRoute.name;
1295
+ }
1296
+ onLoad((query) => {
1297
+ syncRoute(query);
1298
+ });
1299
+ onShow(() => {
1300
+ syncRoute();
1301
+ });
1302
+ onRouteDone(() => {
1303
+ syncRoute();
1304
+ });
1305
+ return readonly(routeState);
1306
+ }
1304
1307
  /**
1305
- * @description 获取高阶路由导航器(对齐 Vue Router 心智)
1308
+ * @description 获取当前组件路径语义的原生 Router
1306
1309
  */
1307
- function useRouter(options = {}) {
1310
+ function useNativeRouter() {
1311
+ return useNativeRouter$1();
1312
+ }
1313
+ /**
1314
+ * @description 获取当前页面路径语义的原生 Page Router
1315
+ */
1316
+ function useNativePageRouter() {
1317
+ return useNativePageRouter$1();
1318
+ }
1319
+ //#endregion
1320
+ //#region src/router/createRouter.ts
1321
+ /**
1322
+ * @description 创建高阶路由导航器(对齐 Vue Router 的 createRouter 心智)
1323
+ */
1324
+ function createRouter(options = {}) {
1308
1325
  var _options$maxRedirects, _options$paramsMode, _options$rejectOnErro, _options$parseQuery, _options$stringifyQue, _options$tabBarEntrie;
1309
1326
  const nativeRouter = useNativeRouter();
1310
1327
  const route = useRoute();
@@ -1346,10 +1363,6 @@ function useRouter(options = {}) {
1346
1363
  function resolve(to) {
1347
1364
  return resolveWithCodec(to, route.path);
1348
1365
  }
1349
- function install(_app) {}
1350
- function isReady() {
1351
- return readyPromise;
1352
- }
1353
1366
  const navigationApi = createNavigationApi({
1354
1367
  nativeRouter,
1355
1368
  route,
@@ -1391,13 +1404,20 @@ function useRouter(options = {}) {
1391
1404
  errorHandlers.delete(handler);
1392
1405
  };
1393
1406
  }
1394
- return {
1407
+ const router = {
1395
1408
  nativeRouter,
1396
1409
  options: routerOptions,
1397
1410
  currentRoute: route,
1398
- install,
1411
+ install(app) {
1412
+ var _config;
1413
+ setActiveRouter(router);
1414
+ const globalProperties = app === null || app === void 0 || (_config = app.config) === null || _config === void 0 ? void 0 : _config.globalProperties;
1415
+ if (globalProperties) globalProperties.$router = router;
1416
+ },
1399
1417
  resolve,
1400
- isReady,
1418
+ isReady() {
1419
+ return readyPromise;
1420
+ },
1401
1421
  push: navigationApi.push,
1402
1422
  replace: navigationApi.replace,
1403
1423
  back: navigationApi.back,
@@ -1413,6 +1433,18 @@ function useRouter(options = {}) {
1413
1433
  afterEach,
1414
1434
  onError
1415
1435
  };
1436
+ setActiveRouter(router);
1437
+ return router;
1438
+ }
1439
+ //#endregion
1440
+ //#region src/router/useRouter.ts
1441
+ /**
1442
+ * @description 获取当前已创建的路由实例。
1443
+ */
1444
+ function useRouter() {
1445
+ const router = getActiveRouter();
1446
+ if (router) return router;
1447
+ throw new Error("useRouter() 未找到已创建的 router 实例。请先在 setup() 中调用 createRouter()。");
1416
1448
  }
1417
1449
  //#endregion
1418
- export { NavigationFailureType, createNavigationFailure, isNavigationFailure, parseQuery, resolveRouteLocation, stringifyQuery, useNativePageRouter, useNativeRouter, useRoute, useRouter };
1450
+ export { NavigationFailureType, createNavigationFailure, createRouter, isNavigationFailure, parseQuery, resolveRouteLocation, stringifyQuery, useNativePageRouter, useNativeRouter, useRoute, useRouter };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "wevu",
3
3
  "type": "module",
4
- "version": "6.7.6",
4
+ "version": "6.8.0",
5
5
  "description": "Vue 3 风格的小程序运行时,包含响应式、diff+setData 与轻量状态管理",
6
6
  "author": "ice breaker <1324318532@qq.com>",
7
7
  "license": "MIT",
@@ -95,8 +95,8 @@
95
95
  },
96
96
  "dependencies": {
97
97
  "vue": "^3.5.30",
98
- "@wevu/api": "0.2.0",
99
- "@wevu/compiler": "6.7.6"
98
+ "@wevu/api": "0.2.1",
99
+ "@wevu/compiler": "6.8.0"
100
100
  },
101
101
  "scripts": {
102
102
  "dev": "tsdown -w",