@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
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2020 Vanelink
3
+ Copyright (c) 2020 Esmx Team
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md ADDED
@@ -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>Vue integration for <a href="https://github.com/esmnext/esmx/tree/master/packages/router">@esmx/router</a> - A universal router that works seamlessly with both Vue 2.7+ and Vue 3.</p>
24
+
25
+ <p>
26
+ English | <a href="https://github.com/esmnext/esmx/blob/master/packages/router-vue/README.zh-CN.md">中文</a>
27
+ </p>
28
+ </div>
29
+
30
+
31
+
32
+ ## Features
33
+
34
+ ✨ **Universal Vue Support** - Works with both Vue 2.7+ and Vue 3
35
+ 🎯 **Composition API First** - Built for modern Vue development
36
+ 🔗 **Seamless Integration** - Drop-in replacement for Vue Router
37
+ 🚀 **TypeScript Ready** - Full TypeScript support with excellent DX
38
+ ⚡ **High Performance** - Optimized for production use
39
+ 🔄 **SSR Compatible** - Server-side rendering support
40
+
41
+ ## Installation
42
+
43
+ ```bash
44
+ npm install @esmx/router @esmx/router-vue
45
+ ```
46
+
47
+ ## Quick Start
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
+ // Install the plugin
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
+ // Install the plugin
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
+ ## Basic Usage
111
+
112
+ ### Template Usage
113
+
114
+ ```vue
115
+ <template>
116
+ <div id="app">
117
+ <nav>
118
+ <RouterLink to="/">Home</RouterLink>
119
+ <RouterLink to="/about">About</RouterLink>
120
+ <RouterLink to="/users/123">User Profile</RouterLink>
121
+ </nav>
122
+
123
+ <!-- Route components will be rendered here -->
124
+ <RouterView />
125
+ </div>
126
+ </template>
127
+ ```
128
+
129
+ ### Composition 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
+ // Programmatic navigation
140
+ const goToAbout = () => {
141
+ router.push('/about');
142
+ };
143
+
144
+ const goBack = () => {
145
+ router.back();
146
+ };
147
+
148
+ // Watch route changes
149
+ watch(() => route.path, (newPath) => {
150
+ // Handle route change logic here
151
+ });
152
+ </script>
153
+
154
+ <template>
155
+ <div>
156
+ <h1>{{ route.meta?.title || 'Page' }}</h1>
157
+ <p>Current path: {{ route.path }}</p>
158
+ <p>Route params: {{ JSON.stringify(route.params) }}</p>
159
+ <p>Query params: {{ JSON.stringify(route.query) }}</p>
160
+
161
+ <button @click="goToAbout">Go to About Page</button>
162
+ <button @click="goBack">Go Back</button>
163
+ </div>
164
+ </template>
165
+ ```
166
+
167
+ ### Options 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
+ // Access current route information
180
+ },
181
+
182
+ methods: {
183
+ navigate() {
184
+ const router = getRouter(this);
185
+ router.push('/dashboard');
186
+ }
187
+ }
188
+ });
189
+ </script>
190
+ ```
191
+
192
+ ## API Reference
193
+
194
+ ### Components
195
+
196
+ #### RouterLink
197
+
198
+ A component for creating navigation links.
199
+
200
+ **Props:**
201
+
202
+ | Prop | Type | Default | Description |
203
+ |------|------|---------|-------------|
204
+ | `to` | `string` \| `RouteLocationInput` | - | Target route location |
205
+ | `type` | `RouterLinkType` | `'push'` | Navigation type (`'push'` \| `'replace'` \| `'pushWindow'` \| `'replaceWindow'` \| `'pushLayer'`) |
206
+ | `exact` | `RouteMatchType` | `'include'` | Active state matching (`'include'` \| `'exact'` \| `'route'`) |
207
+ | `activeClass` | `string` | - | CSS class for active state |
208
+ | `event` | `string` \| `string[]` | `'click'` | Events that trigger navigation |
209
+ | `tag` | `string` | `'a'` | HTML tag to render |
210
+ | `layerOptions` | `RouterLayerOptions` | - | Layer navigation options (used with `type="pushLayer"`) |
211
+
212
+ **Usage:**
213
+
214
+ ```vue
215
+ <template>
216
+ <!-- Basic link -->
217
+ <RouterLink to="/home">Home</RouterLink>
218
+
219
+ <!-- Replace navigation -->
220
+ <RouterLink to="/login" type="replace">Login</RouterLink>
221
+
222
+ <!-- Custom styling -->
223
+ <RouterLink
224
+ to="/dashboard"
225
+ active-class="nav-active"
226
+ exact="exact"
227
+ >
228
+ Dashboard
229
+ </RouterLink>
230
+
231
+ <!-- Custom tag -->
232
+ <RouterLink to="/submit" tag="button" class="btn">
233
+ Submit
234
+ </RouterLink>
235
+ </template>
236
+ ```
237
+
238
+ #### RouterView
239
+
240
+ A component that renders the matched route component.
241
+
242
+ **Usage:**
243
+
244
+ ```vue
245
+ <template>
246
+ <div>
247
+ <!-- Root level routes render here -->
248
+ <RouterView />
249
+
250
+ <!-- Nested routes will render in child RouterView components -->
251
+ <!-- Each RouterView automatically handles the correct depth -->
252
+ </div>
253
+ </template>
254
+ ```
255
+
256
+ ### Composition API
257
+
258
+ #### useRouter()
259
+
260
+ Get the router instance for navigation.
261
+
262
+ ```typescript
263
+ function useRouter(): Router
264
+ ```
265
+
266
+ **Usage:**
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
+ Get the current route information (reactive).
283
+
284
+ ```typescript
285
+ function useRoute(): Route
286
+ ```
287
+
288
+ **Usage:**
289
+
290
+ ```vue
291
+ <script setup>
292
+ import { useRoute } from '@esmx/router-vue';
293
+
294
+ const route = useRoute();
295
+
296
+ // Access route properties
297
+ // route.path - Current path
298
+ // route.params - Route parameters
299
+ // route.query - Query parameters
300
+ // route.meta - Route metadata
301
+ </script>
302
+ ```
303
+
304
+ #### useProvideRouter()
305
+
306
+ Provide router context to child components.
307
+
308
+ ```typescript
309
+ function useProvideRouter(router: Router): void
310
+ ```
311
+
312
+ **Usage:**
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
+ // In your app's setup function
324
+ setup() {
325
+ useProvideRouter(router);
326
+ }
327
+ ```
328
+
329
+ #### useLink()
330
+
331
+ Create reactive link helpers for custom navigation components.
332
+
333
+ ```typescript
334
+ function useLink(props: RouterLinkProps): ComputedRef<RouterLinkResolved>
335
+ ```
336
+
337
+ **Usage:**
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
+ Custom Link
357
+ </a>
358
+ </template>
359
+ ```
360
+
361
+ ### Options API
362
+
363
+ #### getRouter()
364
+
365
+ Get router instance in Options API components.
366
+
367
+ ```typescript
368
+ function getRouter(instance: VueInstance): Router
369
+ ```
370
+
371
+ #### getRoute()
372
+
373
+ Get current route in Options API components.
374
+
375
+ ```typescript
376
+ function getRoute(instance: VueInstance): Route
377
+ ```
378
+
379
+ ### Plugin
380
+
381
+ #### RouterPlugin
382
+
383
+ Vue plugin that registers RouterLink and RouterView components globally.
384
+
385
+ ```typescript
386
+ const RouterPlugin = {
387
+ install(app: App): void
388
+ }
389
+ ```
390
+
391
+ **Usage:**
392
+
393
+ ```typescript
394
+ // Vue 3
395
+ app.use(RouterPlugin);
396
+
397
+ // Vue 2
398
+ Vue.use(RouterPlugin);
399
+ ```
400
+
401
+ ## TypeScript Support
402
+
403
+ This package provides full TypeScript support for both Vue 2.7+ and Vue 3. For Options API usage, the package automatically augments Vue component instances with `$router` and `$route` properties, allowing you to access them directly in templates and component methods.
404
+
405
+ ```typescript
406
+ // Options API type augmentation (automatic)
407
+ declare module 'vue/types/vue' {
408
+ interface Vue {
409
+ readonly $router: Router;
410
+ readonly $route: Route;
411
+ }
412
+ }
413
+ ```
414
+
415
+ **Options API Usage:**
416
+
417
+ ```vue
418
+ <template>
419
+ <div>
420
+ <!-- Direct access without 'this.' -->
421
+ <p>Current path: {{ $route.path }}</p>
422
+ <button @click="navigate">Navigate to About Page</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 knows about $router and $route
433
+ this.$router.push('/about');
434
+ // Access current route: this.$route.path
435
+ }
436
+ }
437
+ });
438
+ </script>
439
+ ```
440
+
441
+ ## Advanced Usage
442
+
443
+ ### Custom Link Component
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
+ ### Route Guards in Components
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
+ // Add route guard
488
+ const unregister = router.beforeEach((to, from) => {
489
+ // Check if route requires authentication (isAuthenticated is your auth function)
490
+ if (to.meta?.requiresAuth && !isAuthenticated()) {
491
+ return '/login';
492
+ }
493
+ });
494
+
495
+ // Cleanup on unmount
496
+ onBeforeUnmount(unregister);
497
+ });
498
+ </script>
499
+ ```
500
+
501
+ ## Migration from Vue Router
502
+
503
+ ### Key Differences
504
+
505
+ 1. **Router Creation**: Use `new Router()` constructor from `@esmx/router`
506
+ 2. **Context Provision**: Use `useProvideRouter()` instead of router installation
507
+ 3. **Component Registration**: Use `RouterPlugin` for global components
508
+
509
+ ### Migration Example
510
+
511
+ **Before (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
+ **After (@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
+ ## Browser Support
549
+
550
+ - **Modern browsers** that support ES modules (`import`/`export`) and dynamic imports (`import()`)
551
+
552
+ ## Contributing
553
+
554
+ We welcome contributions! Please feel free to submit issues and pull requests.
555
+
556
+ ## License
557
+
558
+ MIT © [Esmx Team](https://github.com/esmnext/esmx)
559
+
560
+ ## Related Packages
561
+
562
+ - [@esmx/router](https://github.com/esmnext/esmx/tree/master/packages/router) - Core router package
563
+ - [@esmx/core](https://github.com/esmnext/esmx/tree/master/packages/core) - Esmx core framework