@esmx/router-vue 3.0.0-rc.103
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/LICENSE +21 -0
- package/README.md +570 -0
- package/README.zh-CN.md +570 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.mjs +13 -0
- package/dist/index.test.d.ts +1 -0
- package/dist/index.test.mjs +216 -0
- package/dist/plugin.d.ts +61 -0
- package/dist/plugin.mjs +41 -0
- package/dist/plugin.test.d.ts +1 -0
- package/dist/plugin.test.mjs +631 -0
- package/dist/router-link.d.ts +220 -0
- package/dist/router-link.mjs +119 -0
- package/dist/router-link.test.d.ts +1 -0
- package/dist/router-link.test.mjs +663 -0
- package/dist/router-view.d.ts +31 -0
- package/dist/router-view.mjs +15 -0
- package/dist/router-view.test.d.ts +1 -0
- package/dist/router-view.test.mjs +676 -0
- package/dist/run-with-context.test.d.ts +1 -0
- package/dist/run-with-context.test.mjs +57 -0
- package/dist/use.d.ts +260 -0
- package/dist/use.mjs +125 -0
- package/dist/use.test.d.ts +1 -0
- package/dist/use.test.mjs +381 -0
- package/dist/util.d.ts +20 -0
- package/dist/util.mjs +49 -0
- package/dist/util.test.d.ts +4 -0
- package/dist/util.test.mjs +604 -0
- package/dist/vue2.d.ts +15 -0
- package/dist/vue2.mjs +0 -0
- package/dist/vue3.d.ts +13 -0
- package/dist/vue3.mjs +0 -0
- package/package.json +85 -0
- package/src/index.test.ts +273 -0
- package/src/index.ts +15 -0
- package/src/plugin.test.ts +812 -0
- package/src/plugin.ts +107 -0
- package/src/router-link.test.ts +830 -0
- package/src/router-link.ts +172 -0
- package/src/router-view.test.ts +840 -0
- package/src/router-view.ts +59 -0
- package/src/run-with-context.test.ts +64 -0
- package/src/use.test.ts +484 -0
- package/src/use.ts +416 -0
- package/src/util.test.ts +760 -0
- package/src/util.ts +85 -0
- package/src/vue2.ts +18 -0
- package/src/vue3.ts +15 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2020 Esmx Team
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,570 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="https://esmx.dev/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://esmx.dev/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
|
|
45
|
+
npm install @esmx/router @esmx/router-vue
|
|
46
|
+
|
|
47
|
+
# pnpm
|
|
48
|
+
pnpm add @esmx/router @esmx/router-vue
|
|
49
|
+
|
|
50
|
+
# yarn
|
|
51
|
+
yarn add @esmx/router @esmx/router-vue
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## π Quick Start
|
|
55
|
+
|
|
56
|
+
### Vue 3
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
import { createApp, h } from 'vue';
|
|
60
|
+
import { Router, RouterMode } from '@esmx/router';
|
|
61
|
+
import { RouterPlugin, useProvideRouter } from '@esmx/router-vue';
|
|
62
|
+
import App from './App.vue';
|
|
63
|
+
|
|
64
|
+
const routes = [
|
|
65
|
+
{ path: '/', component: () => import('./views/Home.vue') },
|
|
66
|
+
{ path: '/about', component: () => import('./views/About.vue') }
|
|
67
|
+
];
|
|
68
|
+
|
|
69
|
+
const router = new Router({
|
|
70
|
+
routes,
|
|
71
|
+
mode: RouterMode.history
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const app = createApp({
|
|
75
|
+
setup() {
|
|
76
|
+
useProvideRouter(router);
|
|
77
|
+
return {};
|
|
78
|
+
},
|
|
79
|
+
render: () => h(App)
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// Install the plugin
|
|
83
|
+
app.use(RouterPlugin);
|
|
84
|
+
|
|
85
|
+
app.mount('#app');
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Vue 2.7+
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
import Vue from 'vue';
|
|
92
|
+
import { Router, RouterMode } from '@esmx/router';
|
|
93
|
+
import { RouterPlugin, useProvideRouter } from '@esmx/router-vue';
|
|
94
|
+
import App from './App.vue';
|
|
95
|
+
|
|
96
|
+
const routes = [
|
|
97
|
+
{ path: '/', component: () => import('./views/Home.vue') },
|
|
98
|
+
{ path: '/about', component: () => import('./views/About.vue') }
|
|
99
|
+
];
|
|
100
|
+
|
|
101
|
+
const router = new Router({
|
|
102
|
+
routes,
|
|
103
|
+
mode: RouterMode.history
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// Install the plugin
|
|
107
|
+
Vue.use(RouterPlugin);
|
|
108
|
+
|
|
109
|
+
new Vue({
|
|
110
|
+
setup() {
|
|
111
|
+
useProvideRouter(router);
|
|
112
|
+
},
|
|
113
|
+
render: h => h(App)
|
|
114
|
+
}).$mount('#app');
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Basic Usage
|
|
118
|
+
|
|
119
|
+
### Template Usage
|
|
120
|
+
|
|
121
|
+
```vue
|
|
122
|
+
<template>
|
|
123
|
+
<div id="app">
|
|
124
|
+
<nav>
|
|
125
|
+
<RouterLink to="/">Home</RouterLink>
|
|
126
|
+
<RouterLink to="/about">About</RouterLink>
|
|
127
|
+
<RouterLink to="/users/123">User Profile</RouterLink>
|
|
128
|
+
</nav>
|
|
129
|
+
|
|
130
|
+
<!-- Route components will be rendered here -->
|
|
131
|
+
<RouterView />
|
|
132
|
+
</div>
|
|
133
|
+
</template>
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Composition API
|
|
137
|
+
|
|
138
|
+
```vue
|
|
139
|
+
<script setup lang="ts">
|
|
140
|
+
import { useRouter, useRoute } from '@esmx/router-vue';
|
|
141
|
+
import { watch } from 'vue';
|
|
142
|
+
|
|
143
|
+
const router = useRouter();
|
|
144
|
+
const route = useRoute();
|
|
145
|
+
|
|
146
|
+
// Programmatic navigation
|
|
147
|
+
const goToAbout = () => {
|
|
148
|
+
router.push('/about');
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
const goBack = () => {
|
|
152
|
+
router.back();
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
// Watch route changes
|
|
156
|
+
watch(() => route.path, (newPath) => {
|
|
157
|
+
// Handle route change logic here
|
|
158
|
+
});
|
|
159
|
+
</script>
|
|
160
|
+
|
|
161
|
+
<template>
|
|
162
|
+
<div>
|
|
163
|
+
<h1>{{ route.meta?.title || 'Page' }}</h1>
|
|
164
|
+
<p>Current path: {{ route.path }}</p>
|
|
165
|
+
<p>Route params: {{ JSON.stringify(route.params) }}</p>
|
|
166
|
+
<p>Query params: {{ JSON.stringify(route.query) }}</p>
|
|
167
|
+
|
|
168
|
+
<button @click="goToAbout">Go to About Page</button>
|
|
169
|
+
<button @click="goBack">Go Back</button>
|
|
170
|
+
</div>
|
|
171
|
+
</template>
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Options API
|
|
175
|
+
|
|
176
|
+
```vue
|
|
177
|
+
<script>
|
|
178
|
+
import { defineComponent } from 'vue';
|
|
179
|
+
import { getRouter, getRoute } from '@esmx/router-vue';
|
|
180
|
+
|
|
181
|
+
export default defineComponent({
|
|
182
|
+
mounted() {
|
|
183
|
+
const router = getRouter(this);
|
|
184
|
+
const route = getRoute(this);
|
|
185
|
+
|
|
186
|
+
// Access current route information
|
|
187
|
+
},
|
|
188
|
+
|
|
189
|
+
methods: {
|
|
190
|
+
navigate() {
|
|
191
|
+
const router = getRouter(this);
|
|
192
|
+
router.push('/dashboard');
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
</script>
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## π API Reference
|
|
200
|
+
|
|
201
|
+
### Components
|
|
202
|
+
|
|
203
|
+
#### RouterLink
|
|
204
|
+
|
|
205
|
+
A component for creating navigation links.
|
|
206
|
+
|
|
207
|
+
**Props:**
|
|
208
|
+
|
|
209
|
+
| Prop | Type | Default | Description |
|
|
210
|
+
|------|------|---------|-------------|
|
|
211
|
+
| `to` | `string` \| `RouteLocationInput` | - | Target route location |
|
|
212
|
+
| `type` | `RouterLinkType` | `'push'` | Navigation type (`'push'` \| `'replace'` \| `'pushWindow'` \| `'replaceWindow'` \| `'pushLayer'`) |
|
|
213
|
+
| `exact` | `RouteMatchType` | `'include'` | Active state matching (`'include'` \| `'exact'` \| `'route'`) |
|
|
214
|
+
| `activeClass` | `string` | - | CSS class for active state |
|
|
215
|
+
| `event` | `string` \| `string[]` | `'click'` | Events that trigger navigation |
|
|
216
|
+
| `tag` | `string` | `'a'` | HTML tag to render |
|
|
217
|
+
| `layerOptions` | `RouterLayerOptions` | - | Layer navigation options (used with `type="pushLayer"`) |
|
|
218
|
+
|
|
219
|
+
**Usage:**
|
|
220
|
+
|
|
221
|
+
```vue
|
|
222
|
+
<template>
|
|
223
|
+
<!-- Basic link -->
|
|
224
|
+
<RouterLink to="/home">Home</RouterLink>
|
|
225
|
+
|
|
226
|
+
<!-- Replace navigation -->
|
|
227
|
+
<RouterLink to="/login" type="replace">Login</RouterLink>
|
|
228
|
+
|
|
229
|
+
<!-- Custom styling -->
|
|
230
|
+
<RouterLink
|
|
231
|
+
to="/dashboard"
|
|
232
|
+
active-class="nav-active"
|
|
233
|
+
exact="exact"
|
|
234
|
+
>
|
|
235
|
+
Dashboard
|
|
236
|
+
</RouterLink>
|
|
237
|
+
|
|
238
|
+
<!-- Custom tag -->
|
|
239
|
+
<RouterLink to="/submit" tag="button" class="btn">
|
|
240
|
+
Submit
|
|
241
|
+
</RouterLink>
|
|
242
|
+
</template>
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
#### RouterView
|
|
246
|
+
|
|
247
|
+
A component that renders the matched route component.
|
|
248
|
+
|
|
249
|
+
**Usage:**
|
|
250
|
+
|
|
251
|
+
```vue
|
|
252
|
+
<template>
|
|
253
|
+
<div>
|
|
254
|
+
<!-- Root level routes render here -->
|
|
255
|
+
<RouterView />
|
|
256
|
+
|
|
257
|
+
<!-- Nested routes will render in child RouterView components -->
|
|
258
|
+
<!-- Each RouterView automatically handles the correct depth -->
|
|
259
|
+
</div>
|
|
260
|
+
</template>
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### Composition API
|
|
264
|
+
|
|
265
|
+
#### useRouter()
|
|
266
|
+
|
|
267
|
+
Get the router instance for navigation.
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
function useRouter(): Router
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
**Usage:**
|
|
274
|
+
|
|
275
|
+
```vue
|
|
276
|
+
<script setup>
|
|
277
|
+
import { useRouter } from '@esmx/router-vue';
|
|
278
|
+
|
|
279
|
+
const router = useRouter();
|
|
280
|
+
|
|
281
|
+
const navigate = () => {
|
|
282
|
+
router.push('/about');
|
|
283
|
+
};
|
|
284
|
+
</script>
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
#### useRoute()
|
|
288
|
+
|
|
289
|
+
Get the current route information (reactive).
|
|
290
|
+
|
|
291
|
+
```typescript
|
|
292
|
+
function useRoute(): Route
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
**Usage:**
|
|
296
|
+
|
|
297
|
+
```vue
|
|
298
|
+
<script setup>
|
|
299
|
+
import { useRoute } from '@esmx/router-vue';
|
|
300
|
+
|
|
301
|
+
const route = useRoute();
|
|
302
|
+
|
|
303
|
+
// Access route properties
|
|
304
|
+
// route.path - Current path
|
|
305
|
+
// route.params - Route parameters
|
|
306
|
+
// route.query - Query parameters
|
|
307
|
+
// route.meta - Route metadata
|
|
308
|
+
</script>
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
#### useProvideRouter()
|
|
312
|
+
|
|
313
|
+
Provide router context to child components.
|
|
314
|
+
|
|
315
|
+
```typescript
|
|
316
|
+
function useProvideRouter(router: Router): void
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
**Usage:**
|
|
320
|
+
|
|
321
|
+
```typescript
|
|
322
|
+
import { Router, RouterMode } from '@esmx/router';
|
|
323
|
+
import { useProvideRouter } from '@esmx/router-vue';
|
|
324
|
+
|
|
325
|
+
const router = new Router({
|
|
326
|
+
routes,
|
|
327
|
+
mode: RouterMode.history
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
// In your app's setup function
|
|
331
|
+
setup() {
|
|
332
|
+
useProvideRouter(router);
|
|
333
|
+
}
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
#### useLink()
|
|
337
|
+
|
|
338
|
+
Create reactive link helpers for custom navigation components.
|
|
339
|
+
|
|
340
|
+
```typescript
|
|
341
|
+
function useLink(props: RouterLinkProps): ComputedRef<RouterLinkResolved>
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
**Usage:**
|
|
345
|
+
|
|
346
|
+
```vue
|
|
347
|
+
<script setup>
|
|
348
|
+
import { useLink } from '@esmx/router-vue';
|
|
349
|
+
|
|
350
|
+
const link = useLink({
|
|
351
|
+
to: '/home',
|
|
352
|
+
type: 'push',
|
|
353
|
+
exact: 'include'
|
|
354
|
+
}).value;
|
|
355
|
+
</script>
|
|
356
|
+
|
|
357
|
+
<template>
|
|
358
|
+
<a
|
|
359
|
+
v-bind="link.attributes"
|
|
360
|
+
v-on="link.createEventHandlers()"
|
|
361
|
+
:class="{ active: link.isActive }"
|
|
362
|
+
>
|
|
363
|
+
Custom Link
|
|
364
|
+
</a>
|
|
365
|
+
</template>
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### Options API
|
|
369
|
+
|
|
370
|
+
#### getRouter()
|
|
371
|
+
|
|
372
|
+
Get router instance in Options API components.
|
|
373
|
+
|
|
374
|
+
```typescript
|
|
375
|
+
function getRouter(instance: VueInstance): Router
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
#### getRoute()
|
|
379
|
+
|
|
380
|
+
Get current route in Options API components.
|
|
381
|
+
|
|
382
|
+
```typescript
|
|
383
|
+
function getRoute(instance: VueInstance): Route
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### Plugin
|
|
387
|
+
|
|
388
|
+
#### RouterPlugin
|
|
389
|
+
|
|
390
|
+
Vue plugin that registers RouterLink and RouterView components globally.
|
|
391
|
+
|
|
392
|
+
```typescript
|
|
393
|
+
const RouterPlugin = {
|
|
394
|
+
install(app: App): void
|
|
395
|
+
}
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
**Usage:**
|
|
399
|
+
|
|
400
|
+
```typescript
|
|
401
|
+
// Vue 3
|
|
402
|
+
app.use(RouterPlugin);
|
|
403
|
+
|
|
404
|
+
// Vue 2
|
|
405
|
+
Vue.use(RouterPlugin);
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
## TypeScript Support
|
|
409
|
+
|
|
410
|
+
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.
|
|
411
|
+
|
|
412
|
+
```typescript
|
|
413
|
+
// Options API type augmentation (automatic)
|
|
414
|
+
declare module 'vue/types/vue' {
|
|
415
|
+
interface Vue {
|
|
416
|
+
readonly $router: Router;
|
|
417
|
+
readonly $route: Route;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
**Options API Usage:**
|
|
423
|
+
|
|
424
|
+
```vue
|
|
425
|
+
<template>
|
|
426
|
+
<div>
|
|
427
|
+
<!-- Direct access without 'this.' -->
|
|
428
|
+
<p>Current path: {{ $route.path }}</p>
|
|
429
|
+
<button @click="navigate">Navigate to About Page</button>
|
|
430
|
+
</div>
|
|
431
|
+
</template>
|
|
432
|
+
|
|
433
|
+
<script lang="ts">
|
|
434
|
+
import { defineComponent } from 'vue';
|
|
435
|
+
|
|
436
|
+
export default defineComponent({
|
|
437
|
+
methods: {
|
|
438
|
+
navigate() {
|
|
439
|
+
// TypeScript knows about $router and $route
|
|
440
|
+
this.$router.push('/about');
|
|
441
|
+
// Access current route: this.$route.path
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
</script>
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
## Advanced Usage
|
|
449
|
+
|
|
450
|
+
### Custom Link Component
|
|
451
|
+
|
|
452
|
+
```vue
|
|
453
|
+
<script setup lang="ts">
|
|
454
|
+
import { useLink } from '@esmx/router-vue';
|
|
455
|
+
import type { RouterLinkProps } from '@esmx/router';
|
|
456
|
+
|
|
457
|
+
interface Props extends RouterLinkProps {
|
|
458
|
+
icon?: string;
|
|
459
|
+
disabled?: boolean;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
const props = defineProps<Props>();
|
|
463
|
+
|
|
464
|
+
const link = useLink(props).value;
|
|
465
|
+
</script>
|
|
466
|
+
|
|
467
|
+
<template>
|
|
468
|
+
<button
|
|
469
|
+
v-bind="link.attributes"
|
|
470
|
+
v-on="link.createEventHandlers()"
|
|
471
|
+
:class="{
|
|
472
|
+
active: link.isActive,
|
|
473
|
+
disabled: disabled
|
|
474
|
+
}"
|
|
475
|
+
:disabled="disabled"
|
|
476
|
+
>
|
|
477
|
+
<i v-if="icon" :class="icon" />
|
|
478
|
+
<slot />
|
|
479
|
+
</button>
|
|
480
|
+
</template>
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
### Route Guards in Components
|
|
484
|
+
|
|
485
|
+
```vue
|
|
486
|
+
<script setup>
|
|
487
|
+
import { useRouter, useRoute } from '@esmx/router-vue';
|
|
488
|
+
import { onMounted, onBeforeUnmount } from 'vue';
|
|
489
|
+
|
|
490
|
+
const router = useRouter();
|
|
491
|
+
const route = useRoute();
|
|
492
|
+
|
|
493
|
+
onMounted(() => {
|
|
494
|
+
// Add route guard
|
|
495
|
+
const unregister = router.beforeEach((to, from) => {
|
|
496
|
+
// Check if route requires authentication (isAuthenticated is your auth function)
|
|
497
|
+
if (to.meta?.requiresAuth && !isAuthenticated()) {
|
|
498
|
+
return '/login';
|
|
499
|
+
}
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
// Cleanup on unmount
|
|
503
|
+
onBeforeUnmount(unregister);
|
|
504
|
+
});
|
|
505
|
+
</script>
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
## Migration from Vue Router
|
|
509
|
+
|
|
510
|
+
### Key Differences
|
|
511
|
+
|
|
512
|
+
1. **Router Creation**: Use `new Router()` constructor from `@esmx/router`
|
|
513
|
+
2. **Context Provision**: Use `useProvideRouter()` instead of router installation
|
|
514
|
+
3. **Component Registration**: Use `RouterPlugin` for global components
|
|
515
|
+
|
|
516
|
+
### Migration Example
|
|
517
|
+
|
|
518
|
+
**Before (Vue Router):**
|
|
519
|
+
|
|
520
|
+
```typescript
|
|
521
|
+
import { createRouter, createWebHistory } from 'vue-router';
|
|
522
|
+
|
|
523
|
+
const router = createRouter({
|
|
524
|
+
history: createWebHistory(),
|
|
525
|
+
routes
|
|
526
|
+
});
|
|
527
|
+
|
|
528
|
+
app.use(router);
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
**After (@esmx/router-vue):**
|
|
532
|
+
|
|
533
|
+
```typescript
|
|
534
|
+
import { Router, RouterMode } from '@esmx/router';
|
|
535
|
+
import { RouterPlugin, useProvideRouter } from '@esmx/router-vue';
|
|
536
|
+
import { createApp, h } from 'vue';
|
|
537
|
+
import App from './App.vue';
|
|
538
|
+
|
|
539
|
+
const router = new Router({
|
|
540
|
+
routes,
|
|
541
|
+
mode: RouterMode.history
|
|
542
|
+
});
|
|
543
|
+
|
|
544
|
+
const app = createApp({
|
|
545
|
+
setup() {
|
|
546
|
+
useProvideRouter(router);
|
|
547
|
+
return {};
|
|
548
|
+
},
|
|
549
|
+
render: () => h(App)
|
|
550
|
+
});
|
|
551
|
+
|
|
552
|
+
app.use(RouterPlugin);
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
## Browser Support
|
|
556
|
+
|
|
557
|
+
- **Modern browsers** that support ES modules (`import`/`export`) and dynamic imports (`import()`)
|
|
558
|
+
|
|
559
|
+
## Contributing
|
|
560
|
+
|
|
561
|
+
We welcome contributions! Please feel free to submit issues and pull requests.
|
|
562
|
+
|
|
563
|
+
## π License
|
|
564
|
+
|
|
565
|
+
MIT Β© [Esmx Team](https://github.com/esmnext/esmx)
|
|
566
|
+
|
|
567
|
+
## Related Packages
|
|
568
|
+
|
|
569
|
+
- [@esmx/router](https://github.com/esmnext/esmx/tree/master/packages/router) - Core router package
|
|
570
|
+
- [@esmx/core](https://github.com/esmnext/esmx/tree/master/packages/core) - Esmx core framework
|