@esmx/router-vue 3.0.0-rc.17 → 3.0.0-rc.20

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 (55) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +563 -0
  3. package/README.zh-CN.md +563 -0
  4. package/dist/index.d.ts +6 -4
  5. package/dist/index.mjs +11 -4
  6. package/dist/index.test.d.ts +1 -0
  7. package/dist/index.test.mjs +206 -0
  8. package/dist/plugin.d.ts +61 -11
  9. package/dist/plugin.mjs +32 -16
  10. package/dist/plugin.test.d.ts +1 -0
  11. package/dist/plugin.test.mjs +436 -0
  12. package/dist/router-link.d.ts +202 -0
  13. package/dist/router-link.mjs +84 -0
  14. package/dist/router-link.test.d.ts +1 -0
  15. package/dist/router-link.test.mjs +456 -0
  16. package/dist/router-view.d.ts +31 -0
  17. package/dist/router-view.mjs +17 -0
  18. package/dist/router-view.test.d.ts +1 -0
  19. package/dist/router-view.test.mjs +459 -0
  20. package/dist/use.d.ts +198 -3
  21. package/dist/use.mjs +75 -9
  22. package/dist/use.test.d.ts +1 -0
  23. package/dist/use.test.mjs +461 -0
  24. package/dist/util.d.ts +7 -0
  25. package/dist/util.mjs +24 -0
  26. package/dist/util.test.d.ts +1 -0
  27. package/dist/util.test.mjs +319 -0
  28. package/dist/vue2.d.ts +13 -0
  29. package/dist/vue2.mjs +0 -0
  30. package/dist/vue3.d.ts +13 -0
  31. package/dist/vue3.mjs +0 -0
  32. package/package.json +31 -14
  33. package/src/index.test.ts +263 -0
  34. package/src/index.ts +16 -4
  35. package/src/plugin.test.ts +574 -0
  36. package/src/plugin.ts +92 -31
  37. package/src/router-link.test.ts +569 -0
  38. package/src/router-link.ts +148 -0
  39. package/src/router-view.test.ts +599 -0
  40. package/src/router-view.ts +62 -0
  41. package/src/use.test.ts +616 -0
  42. package/src/use.ts +307 -11
  43. package/src/util.test.ts +418 -0
  44. package/src/util.ts +32 -0
  45. package/src/vue2.ts +16 -0
  46. package/src/vue3.ts +15 -0
  47. package/dist/link.d.ts +0 -101
  48. package/dist/link.mjs +0 -103
  49. package/dist/symbols.d.ts +0 -3
  50. package/dist/symbols.mjs +0 -3
  51. package/dist/view.d.ts +0 -21
  52. package/dist/view.mjs +0 -75
  53. package/src/link.ts +0 -177
  54. package/src/symbols.ts +0 -8
  55. package/src/view.ts +0 -95
@@ -0,0 +1,563 @@
1
+ <div align="center">
2
+ <img src="https://www.esmnext.com/logo.svg?t=2025" width="120" alt="Esmx Logo" />
3
+ <h1>@esmx/router-vue</h1>
4
+
5
+ <div>
6
+ <a href="https://www.npmjs.com/package/@esmx/router-vue">
7
+ <img src="https://img.shields.io/npm/v/@esmx/router-vue.svg" alt="npm version" />
8
+ </a>
9
+ <a href="https://github.com/esmnext/esmx/actions/workflows/build.yml">
10
+ <img src="https://github.com/esmnext/esmx/actions/workflows/build.yml/badge.svg" alt="Build" />
11
+ </a>
12
+ <a href="https://www.esmnext.com/coverage/">
13
+ <img src="https://img.shields.io/badge/coverage-live%20report-brightgreen" alt="Coverage Report" />
14
+ </a>
15
+ <a href="https://nodejs.org/">
16
+ <img src="https://img.shields.io/node/v/@esmx/router-vue.svg" alt="node version" />
17
+ </a>
18
+ <a href="https://bundlephobia.com/package/@esmx/router-vue">
19
+ <img src="https://img.shields.io/bundlephobia/minzip/@esmx/router-vue" alt="size" />
20
+ </a>
21
+ </div>
22
+
23
+ <p><a href="https://github.com/esmnext/esmx/tree/master/packages/router">@esmx/router</a> 的 Vue 集成包 - 一个同时适用于 Vue 2.7+ 和 Vue 3 的通用路由器。</p>
24
+
25
+ <p>
26
+ <a href="https://github.com/esmnext/esmx/blob/master/packages/router-vue/README.md">English</a> | 中文
27
+ </p>
28
+ </div>
29
+
30
+
31
+
32
+ ## 特性
33
+
34
+ ✨ **通用 Vue 支持** - 同时支持 Vue 2.7+ 和 Vue 3
35
+ 🎯 **组合式 API 优先** - 为现代 Vue 开发而构建
36
+ 🔗 **无缝集成** - Vue Router 的替代方案
37
+ 🚀 **TypeScript 就绪** - 完整的 TypeScript 支持,出色的开发体验
38
+ ⚡ **高性能** - 为生产环境优化
39
+ 🔄 **SSR 兼容** - 支持服务端渲染
40
+
41
+ ## 安装
42
+
43
+ ```bash
44
+ npm install @esmx/router @esmx/router-vue
45
+ ```
46
+
47
+ ## 快速开始
48
+
49
+ ### Vue 3
50
+
51
+ ```typescript
52
+ import { createApp, h } from 'vue';
53
+ import { Router, RouterMode } from '@esmx/router';
54
+ import { RouterPlugin, useProvideRouter } from '@esmx/router-vue';
55
+ import App from './App.vue';
56
+
57
+ const routes = [
58
+ { path: '/', component: () => import('./views/Home.vue') },
59
+ { path: '/about', component: () => import('./views/About.vue') }
60
+ ];
61
+
62
+ const router = new Router({
63
+ routes,
64
+ mode: RouterMode.history
65
+ });
66
+
67
+ const app = createApp({
68
+ setup() {
69
+ useProvideRouter(router);
70
+ return {};
71
+ },
72
+ render: () => h(App)
73
+ });
74
+
75
+ // 安装插件
76
+ app.use(RouterPlugin);
77
+
78
+ app.mount('#app');
79
+ ```
80
+
81
+ ### Vue 2.7+
82
+
83
+ ```typescript
84
+ import Vue from 'vue';
85
+ import { Router, RouterMode } from '@esmx/router';
86
+ import { RouterPlugin, useProvideRouter } from '@esmx/router-vue';
87
+ import App from './App.vue';
88
+
89
+ const routes = [
90
+ { path: '/', component: () => import('./views/Home.vue') },
91
+ { path: '/about', component: () => import('./views/About.vue') }
92
+ ];
93
+
94
+ const router = new Router({
95
+ routes,
96
+ mode: RouterMode.history
97
+ });
98
+
99
+ // 安装插件
100
+ Vue.use(RouterPlugin);
101
+
102
+ new Vue({
103
+ setup() {
104
+ useProvideRouter(router);
105
+ },
106
+ render: h => h(App)
107
+ }).$mount('#app');
108
+ ```
109
+
110
+ ## 基础用法
111
+
112
+ ### 模板用法
113
+
114
+ ```vue
115
+ <template>
116
+ <div id="app">
117
+ <nav>
118
+ <RouterLink to="/">首页</RouterLink>
119
+ <RouterLink to="/about">关于</RouterLink>
120
+ <RouterLink to="/users/123">用户资料</RouterLink>
121
+ </nav>
122
+
123
+ <!-- 路由组件将在这里渲染 -->
124
+ <RouterView />
125
+ </div>
126
+ </template>
127
+ ```
128
+
129
+ ### 组合式 API
130
+
131
+ ```vue
132
+ <script setup lang="ts">
133
+ import { useRouter, useRoute } from '@esmx/router-vue';
134
+ import { watch } from 'vue';
135
+
136
+ const router = useRouter();
137
+ const route = useRoute();
138
+
139
+ // 编程式导航
140
+ const goToAbout = () => {
141
+ router.push('/about');
142
+ };
143
+
144
+ const goBack = () => {
145
+ router.back();
146
+ };
147
+
148
+ // 监听路由变化
149
+ watch(() => route.path, (newPath) => {
150
+ // 处理路由变化逻辑
151
+ });
152
+ </script>
153
+
154
+ <template>
155
+ <div>
156
+ <h1>{{ route.meta?.title || '页面' }}</h1>
157
+ <p>当前路径: {{ route.path }}</p>
158
+ <p>路由参数: {{ JSON.stringify(route.params) }}</p>
159
+ <p>查询参数: {{ JSON.stringify(route.query) }}</p>
160
+
161
+ <button @click="goToAbout">前往关于页</button>
162
+ <button @click="goBack">返回</button>
163
+ </div>
164
+ </template>
165
+ ```
166
+
167
+ ### 选项式 API
168
+
169
+ ```vue
170
+ <script>
171
+ import { defineComponent } from 'vue';
172
+ import { getRouter, getRoute } from '@esmx/router-vue';
173
+
174
+ export default defineComponent({
175
+ mounted() {
176
+ const router = getRouter(this);
177
+ const route = getRoute(this);
178
+
179
+ // 访问当前路由信息
180
+ },
181
+
182
+ methods: {
183
+ navigate() {
184
+ const router = getRouter(this);
185
+ router.push('/dashboard');
186
+ }
187
+ }
188
+ });
189
+ </script>
190
+ ```
191
+
192
+ ## API 参考
193
+
194
+ ### 组件
195
+
196
+ #### RouterLink
197
+
198
+ 用于创建导航链接的组件。
199
+
200
+ **属性:**
201
+
202
+ | 属性 | 类型 | 默认值 | 描述 |
203
+ |------|------|---------|-------------|
204
+ | `to` | `string` \| `RouteLocationInput` | - | 目标路由位置 |
205
+ | `type` | `RouterLinkType` | `'push'` | 导航类型 (`'push'` \| `'replace'` \| `'pushWindow'` \| `'replaceWindow'` \| `'pushLayer'`) |
206
+ | `exact` | `RouteMatchType` | `'include'` | 激活状态匹配方式 (`'include'` \| `'exact'` \| `'route'`) |
207
+ | `activeClass` | `string` | - | 激活状态的 CSS 类名 |
208
+ | `event` | `string` \| `string[]` | `'click'` | 触发导航的事件 |
209
+ | `tag` | `string` | `'a'` | 要渲染的 HTML 标签 |
210
+ | `layerOptions` | `RouterLayerOptions` | - | 弹层导航选项 (与 `type="pushLayer"` 一起使用) |
211
+
212
+ **用法:**
213
+
214
+ ```vue
215
+ <template>
216
+ <!-- 基础链接 -->
217
+ <RouterLink to="/home">首页</RouterLink>
218
+
219
+ <!-- 替换导航 -->
220
+ <RouterLink to="/login" type="replace">登录</RouterLink>
221
+
222
+ <!-- 自定义样式 -->
223
+ <RouterLink
224
+ to="/dashboard"
225
+ active-class="nav-active"
226
+ exact="exact"
227
+ >
228
+ 仪表板
229
+ </RouterLink>
230
+
231
+ <!-- 自定义标签 -->
232
+ <RouterLink to="/submit" tag="button" class="btn">
233
+ 提交
234
+ </RouterLink>
235
+ </template>
236
+ ```
237
+
238
+ #### RouterView
239
+
240
+ 渲染匹配路由组件的组件。
241
+
242
+ **用法:**
243
+
244
+ ```vue
245
+ <template>
246
+ <div>
247
+ <!-- 根级路由在这里渲染 -->
248
+ <RouterView />
249
+
250
+ <!-- 嵌套路由会在子 RouterView 组件中渲染 -->
251
+ <!-- 每个 RouterView 会自动处理正确的深度 -->
252
+ </div>
253
+ </template>
254
+ ```
255
+
256
+ ### 组合式 API
257
+
258
+ #### useRouter()
259
+
260
+ 获取用于导航的路由器实例。
261
+
262
+ ```typescript
263
+ function useRouter(): Router
264
+ ```
265
+
266
+ **用法:**
267
+
268
+ ```vue
269
+ <script setup>
270
+ import { useRouter } from '@esmx/router-vue';
271
+
272
+ const router = useRouter();
273
+
274
+ const navigate = () => {
275
+ router.push('/about');
276
+ };
277
+ </script>
278
+ ```
279
+
280
+ #### useRoute()
281
+
282
+ 获取当前路由信息(响应式)。
283
+
284
+ ```typescript
285
+ function useRoute(): Route
286
+ ```
287
+
288
+ **用法:**
289
+
290
+ ```vue
291
+ <script setup>
292
+ import { useRoute } from '@esmx/router-vue';
293
+
294
+ const route = useRoute();
295
+
296
+ // 访问路由属性
297
+ // route.path - 当前路径
298
+ // route.params - 路由参数
299
+ // route.query - 查询参数
300
+ // route.meta - 路由元数据
301
+ </script>
302
+ ```
303
+
304
+ #### useProvideRouter()
305
+
306
+ 为子组件提供路由上下文。
307
+
308
+ ```typescript
309
+ function useProvideRouter(router: Router): void
310
+ ```
311
+
312
+ **用法:**
313
+
314
+ ```typescript
315
+ import { Router, RouterMode } from '@esmx/router';
316
+ import { useProvideRouter } from '@esmx/router-vue';
317
+
318
+ const router = new Router({
319
+ routes,
320
+ mode: RouterMode.history
321
+ });
322
+
323
+ // 在应用的 setup 函数中
324
+ setup() {
325
+ useProvideRouter(router);
326
+ }
327
+ ```
328
+
329
+ #### useLink()
330
+
331
+ 为自定义导航组件创建响应式链接助手。
332
+
333
+ ```typescript
334
+ function useLink(props: RouterLinkProps): ComputedRef<RouterLinkResolved>
335
+ ```
336
+
337
+ **用法:**
338
+
339
+ ```vue
340
+ <script setup>
341
+ import { useLink } from '@esmx/router-vue';
342
+
343
+ const link = useLink({
344
+ to: '/home',
345
+ type: 'push',
346
+ exact: 'include'
347
+ }).value;
348
+ </script>
349
+
350
+ <template>
351
+ <a
352
+ v-bind="link.attributes"
353
+ v-on="link.getEventHandlers()"
354
+ :class="{ active: link.isActive }"
355
+ >
356
+ 自定义链接
357
+ </a>
358
+ </template>
359
+ ```
360
+
361
+ ### 选项式 API
362
+
363
+ #### getRouter()
364
+
365
+ 在选项式 API 组件中获取路由器实例。
366
+
367
+ ```typescript
368
+ function getRouter(instance: VueInstance): Router
369
+ ```
370
+
371
+ #### getRoute()
372
+
373
+ 在选项式 API 组件中获取当前路由。
374
+
375
+ ```typescript
376
+ function getRoute(instance: VueInstance): Route
377
+ ```
378
+
379
+ ### 插件
380
+
381
+ #### RouterPlugin
382
+
383
+ 全局注册 RouterLink 和 RouterView 组件的 Vue 插件。
384
+
385
+ ```typescript
386
+ const RouterPlugin = {
387
+ install(app: App): void
388
+ }
389
+ ```
390
+
391
+ **用法:**
392
+
393
+ ```typescript
394
+ // Vue 3
395
+ app.use(RouterPlugin);
396
+
397
+ // Vue 2
398
+ Vue.use(RouterPlugin);
399
+ ```
400
+
401
+ ## TypeScript 支持
402
+
403
+ 此包为 Vue 2.7+ 和 Vue 3 提供完整的 TypeScript 支持。对于选项式 API 用法,包会自动为 Vue 组件实例增强 `$router` 和 `$route` 属性,允许您在模板和组件方法中直接访问它们。
404
+
405
+ ```typescript
406
+ // 选项式 API 类型增强(自动)
407
+ declare module 'vue/types/vue' {
408
+ interface Vue {
409
+ readonly $router: Router;
410
+ readonly $route: Route;
411
+ }
412
+ }
413
+ ```
414
+
415
+ **选项式 API 用法:**
416
+
417
+ ```vue
418
+ <template>
419
+ <div>
420
+ <!-- 直接访问,无需 'this.' -->
421
+ <p>当前路径: {{ $route.path }}</p>
422
+ <button @click="navigate">跳转到关于页面</button>
423
+ </div>
424
+ </template>
425
+
426
+ <script lang="ts">
427
+ import { defineComponent } from 'vue';
428
+
429
+ export default defineComponent({
430
+ methods: {
431
+ navigate() {
432
+ // TypeScript 能够识别 $router 和 $route
433
+ this.$router.push('/about');
434
+ // Access current route: this.$route.path
435
+ }
436
+ }
437
+ });
438
+ </script>
439
+ ```
440
+
441
+ ## 高级用法
442
+
443
+ ### 自定义链接组件
444
+
445
+ ```vue
446
+ <script setup lang="ts">
447
+ import { useLink } from '@esmx/router-vue';
448
+ import type { RouterLinkProps } from '@esmx/router';
449
+
450
+ interface Props extends RouterLinkProps {
451
+ icon?: string;
452
+ disabled?: boolean;
453
+ }
454
+
455
+ const props = defineProps<Props>();
456
+
457
+ const link = useLink(props).value;
458
+ </script>
459
+
460
+ <template>
461
+ <button
462
+ v-bind="link.attributes"
463
+ v-on="link.getEventHandlers()"
464
+ :class="{
465
+ active: link.isActive,
466
+ disabled: disabled
467
+ }"
468
+ :disabled="disabled"
469
+ >
470
+ <i v-if="icon" :class="icon" />
471
+ <slot />
472
+ </button>
473
+ </template>
474
+ ```
475
+
476
+ ### 组件中的路由守卫
477
+
478
+ ```vue
479
+ <script setup>
480
+ import { useRouter, useRoute } from '@esmx/router-vue';
481
+ import { onMounted, onBeforeUnmount } from 'vue';
482
+
483
+ const router = useRouter();
484
+ const route = useRoute();
485
+
486
+ onMounted(() => {
487
+ // 添加路由守卫
488
+ const unregister = router.beforeEach((to, from) => {
489
+ // 检查路由是否需要认证(isAuthenticated 是你的认证函数)
490
+ if (to.meta?.requiresAuth && !isAuthenticated()) {
491
+ return '/login';
492
+ }
493
+ });
494
+
495
+ // 组件卸载时清理
496
+ onBeforeUnmount(unregister);
497
+ });
498
+ </script>
499
+ ```
500
+
501
+ ## 从 Vue Router 迁移
502
+
503
+ ### 主要差异
504
+
505
+ 1. **路由器创建**: 使用 `@esmx/router` 的 `new Router()` 构造函数
506
+ 2. **上下文提供**: 使用 `useProvideRouter()` 而非路由器安装
507
+ 3. **组件注册**: 使用 `RouterPlugin` 进行全局组件注册
508
+
509
+ ### 迁移示例
510
+
511
+ **之前 (Vue Router):**
512
+
513
+ ```typescript
514
+ import { createRouter, createWebHistory } from 'vue-router';
515
+
516
+ const router = createRouter({
517
+ history: createWebHistory(),
518
+ routes
519
+ });
520
+
521
+ app.use(router);
522
+ ```
523
+
524
+ **之后 (@esmx/router-vue):**
525
+
526
+ ```typescript
527
+ import { Router, RouterMode } from '@esmx/router';
528
+ import { RouterPlugin, useProvideRouter } from '@esmx/router-vue';
529
+ import { createApp, h } from 'vue';
530
+ import App from './App.vue';
531
+
532
+ const router = new Router({
533
+ routes,
534
+ mode: RouterMode.history
535
+ });
536
+
537
+ const app = createApp({
538
+ setup() {
539
+ useProvideRouter(router);
540
+ return {};
541
+ },
542
+ render: () => h(App)
543
+ });
544
+
545
+ app.use(RouterPlugin);
546
+ ```
547
+
548
+ ## 浏览器支持
549
+
550
+ - **现代浏览器**:支持 ES 模块 (`import`/`export`) 和动态导入 (`import()`) 的浏览器
551
+
552
+ ## 贡献
553
+
554
+ 我们欢迎贡献!请随时提交 issues 和 pull requests。
555
+
556
+ ## 许可证
557
+
558
+ MIT © [Esmx 团队](https://github.com/esmnext/esmx)
559
+
560
+ ## 相关包
561
+
562
+ - [@esmx/router](https://github.com/esmnext/esmx/tree/master/packages/router) - 核心路由包
563
+ - [@esmx/core](https://github.com/esmnext/esmx/tree/master/packages/core) - Esmx 核心框架
package/dist/index.d.ts CHANGED
@@ -1,4 +1,6 @@
1
- export { RouterVuePlugin } from './plugin';
2
- export { useRouter, useRoute } from './use';
3
- export { RouterLink } from './link';
4
- export { RouterView } from './view';
1
+ export type * from './vue2';
2
+ export type * from './vue3';
3
+ export { useRouter, useRoute, useProvideRouter, useLink, getRoute, getRouter } from './use';
4
+ export { RouterLink } from './router-link';
5
+ export { RouterView } from './router-view';
6
+ export { RouterPlugin } from './plugin';
package/dist/index.mjs CHANGED
@@ -1,4 +1,11 @@
1
- export { RouterVuePlugin } from "./plugin.mjs";
2
- export { useRouter, useRoute } from "./use.mjs";
3
- export { RouterLink } from "./link.mjs";
4
- export { RouterView } from "./view.mjs";
1
+ export {
2
+ useRouter,
3
+ useRoute,
4
+ useProvideRouter,
5
+ useLink,
6
+ getRoute,
7
+ getRouter
8
+ } from "./use.mjs";
9
+ export { RouterLink } from "./router-link.mjs";
10
+ export { RouterView } from "./router-view.mjs";
11
+ export { RouterPlugin } from "./plugin.mjs";
@@ -0,0 +1 @@
1
+ export {};