vitarx-router 3.0.0 → 4.0.0-beta.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/LICENSE +1 -1
- package/README.md +601 -27
- package/dist/components/RouterLink.d.ts +58 -0
- package/dist/components/RouterLink.js +153 -0
- package/dist/components/RouterView.d.ts +28 -0
- package/dist/components/RouterView.js +68 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.js +2 -0
- package/dist/core/constant.d.ts +40 -0
- package/dist/core/constant.js +41 -0
- package/dist/core/helpers.d.ts +150 -0
- package/dist/core/helpers.js +83 -0
- package/dist/core/index.d.ts +6 -0
- package/dist/core/index.js +5 -0
- package/dist/core/normalize/component.d.ts +8 -0
- package/dist/core/normalize/component.js +35 -0
- package/dist/core/normalize/index.d.ts +10 -0
- package/dist/core/normalize/index.js +36 -0
- package/dist/core/normalize/inject-props.d.ts +8 -0
- package/dist/core/normalize/inject-props.js +58 -0
- package/dist/core/router-core.d.ts +272 -0
- package/dist/core/router-core.js +569 -0
- package/dist/core/router-history.d.ts +85 -0
- package/dist/core/router-history.js +217 -0
- package/dist/core/router-memory.d.ts +47 -0
- package/dist/core/router-memory.js +122 -0
- package/dist/core/router-registry.d.ts +133 -0
- package/dist/core/router-registry.js +421 -0
- package/dist/core/router-types.d.ts +1 -0
- package/dist/core/router-types.js +1 -0
- package/dist/core/types/hooks.d.ts +34 -0
- package/dist/core/types/hooks.js +1 -0
- package/dist/core/types/index.d.ts +5 -0
- package/dist/core/types/index.js +1 -0
- package/dist/core/types/navigation.d.ts +198 -0
- package/dist/core/types/navigation.js +1 -0
- package/dist/core/types/options.d.ts +116 -0
- package/dist/core/types/options.js +1 -0
- package/dist/core/types/route.d.ts +184 -0
- package/dist/core/types/route.js +1 -0
- package/dist/core/types/scroll.d.ts +31 -0
- package/dist/core/types/scroll.js +1 -0
- package/dist/core/update.d.ts +8 -0
- package/dist/core/update.js +61 -0
- package/dist/core/utils.d.ts +143 -0
- package/dist/core/utils.js +298 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/vite/auto-routes/definePage.d.ts +10 -0
- package/dist/vite/auto-routes/definePage.js +10 -0
- package/dist/vite/auto-routes/handleHotUpdate.d.ts +34 -0
- package/dist/vite/auto-routes/handleHotUpdate.js +66 -0
- package/dist/vite/auto-routes/index.d.ts +20 -0
- package/dist/vite/auto-routes/index.js +20 -0
- package/dist/vite/core/babelUtils.d.ts +16 -0
- package/dist/vite/core/babelUtils.js +28 -0
- package/dist/vite/core/configUtils.d.ts +76 -0
- package/dist/vite/core/configUtils.js +139 -0
- package/dist/vite/core/constants.d.ts +11 -0
- package/dist/vite/core/constants.js +11 -0
- package/dist/vite/core/generateRoutes.d.ts +74 -0
- package/dist/vite/core/generateRoutes.js +233 -0
- package/dist/vite/core/generateTypes.d.ts +12 -0
- package/dist/vite/core/generateTypes.js +94 -0
- package/dist/vite/core/index.d.ts +40 -0
- package/dist/vite/core/index.js +46 -0
- package/dist/vite/core/logger.d.ts +23 -0
- package/dist/vite/core/logger.js +67 -0
- package/dist/vite/core/parsePage.d.ts +80 -0
- package/dist/vite/core/parsePage.js +906 -0
- package/dist/vite/core/removeDefinePage.d.ts +7 -0
- package/dist/vite/core/removeDefinePage.js +81 -0
- package/dist/vite/core/scanPages.d.ts +35 -0
- package/dist/vite/core/scanPages.js +536 -0
- package/dist/vite/core/types.d.ts +482 -0
- package/dist/vite/core/types.js +1 -0
- package/dist/vite/core/validateOptions.d.ts +29 -0
- package/dist/vite/core/validateOptions.js +140 -0
- package/dist/vite/index.d.ts +66 -0
- package/dist/vite/index.js +211 -0
- package/package.json +47 -28
- package/dist/scripts/type-make.d.ts +0 -19
- package/dist/scripts/type-make.js +0 -66
- package/dist/vitarx-router.d.ts +0 -1494
- package/dist/vitarx-router.es.js +0 -1477
- package/dist/vitarx-router.iife.js +0 -1
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,45 +1,619 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Vitarx Router
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Vitarx 前端框架官方路由解决方案,提供声明式路由配置、导航守卫、动态路由匹配、文件系统路由等企业级功能。
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/vitarx-router)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
[](https://github.com/vitarx-lib/router)
|
|
8
|
+
[](https://router.vitarx.cn)
|
|
9
|
+
|
|
10
|
+
## 特性
|
|
11
|
+
|
|
12
|
+
- 🚀 **多种路由模式** - 支持 Hash、History、Memory 三种路由模式
|
|
13
|
+
- 📁 **文件路由** - 基于 Vite 插件的文件系统路由自动生成
|
|
14
|
+
- 🔒 **导航守卫** - 完整的路由守卫机制,支持权限控制
|
|
15
|
+
- 🔄 **动态路由** - 支持动态参数、正则约束、可选参数
|
|
16
|
+
- 📦 **懒加载** - 内置组件懒加载支持
|
|
17
|
+
- 🎯 **TypeScript** - 完整的类型支持
|
|
18
|
+
- � **滚动行为** - 可自定义路由切换时的滚动行为
|
|
5
19
|
|
|
6
20
|
## 安装
|
|
7
21
|
|
|
8
|
-
```
|
|
22
|
+
```bash
|
|
23
|
+
# 使用 npm
|
|
9
24
|
npm install vitarx-router
|
|
25
|
+
# 或者使用 yarn
|
|
26
|
+
yarn add vitarx-router
|
|
27
|
+
# 或者使用 pnpm
|
|
28
|
+
pnpm add vitarx-router
|
|
10
29
|
```
|
|
11
30
|
|
|
12
|
-
##
|
|
31
|
+
## 快速开始
|
|
32
|
+
|
|
33
|
+
### 1. 创建路由配置
|
|
13
34
|
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
import
|
|
35
|
+
```typescript
|
|
36
|
+
// src/router/index.ts
|
|
37
|
+
import { createRouter, defineRoutes } from 'vitarx-router'
|
|
38
|
+
import Home from '../pages/Home.jsx'
|
|
39
|
+
import About from '../pages/About.jsx'
|
|
17
40
|
|
|
18
|
-
// 定义路由线路
|
|
19
41
|
const routes = defineRoutes(
|
|
42
|
+
{ path: '/', component: Home },
|
|
43
|
+
{ path: '/about', component: About }
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
export const router = createRouter({ routes })
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### 2. 注册路由器
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
// src/main.ts
|
|
53
|
+
import { createApp } from 'vitarx'
|
|
54
|
+
import { router } from './router'
|
|
55
|
+
import App from './App.jsx'
|
|
56
|
+
|
|
57
|
+
createApp(App).use(router).mount('#app')
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 3. 使用路由视图
|
|
61
|
+
|
|
62
|
+
```jsx
|
|
63
|
+
// App.jsx
|
|
64
|
+
import { RouterView } from 'vitarx-router'
|
|
65
|
+
|
|
66
|
+
export default function App() {
|
|
67
|
+
return (
|
|
68
|
+
<div>
|
|
69
|
+
<nav>
|
|
70
|
+
<a href="/">首页</a>
|
|
71
|
+
<a href="/about">关于</a>
|
|
72
|
+
</nav>
|
|
73
|
+
<RouterView />
|
|
74
|
+
</div>
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## 路由模式
|
|
82
|
+
|
|
83
|
+
### Hash 模式(默认)
|
|
84
|
+
|
|
85
|
+
使用 URL hash 实现路由,无需服务器配置。
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
createRouter({
|
|
89
|
+
routes,
|
|
90
|
+
mode: 'hash'
|
|
91
|
+
})
|
|
92
|
+
// URL: https://example.com/#/user/123
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### History 模式
|
|
96
|
+
|
|
97
|
+
使用 HTML5 History API,需要服务器配置支持。
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
createRouter({
|
|
101
|
+
routes,
|
|
102
|
+
mode: 'path'
|
|
103
|
+
})
|
|
104
|
+
// URL: https://example.com/user/123
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**服务器配置(Nginx):**
|
|
108
|
+
|
|
109
|
+
```nginx
|
|
110
|
+
location / {
|
|
111
|
+
try_files $uri $uri/ /index.html;
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Memory 模式
|
|
116
|
+
|
|
117
|
+
不修改 URL,适用于非浏览器环境或测试场景。
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
createRouter({
|
|
121
|
+
routes,
|
|
122
|
+
mode: 'memory'
|
|
123
|
+
})
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## 路由配置
|
|
129
|
+
|
|
130
|
+
### 基本路由
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
import { defineRoutes } from 'vitarx-router'
|
|
134
|
+
|
|
135
|
+
const routes = defineRoutes(
|
|
136
|
+
{ path: '/', component: Home },
|
|
137
|
+
{ path: '/about', component: About },
|
|
138
|
+
{ path: '/contact', component: Contact }
|
|
139
|
+
)
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### 动态路由
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
const routes = defineRoutes(
|
|
146
|
+
// 基本动态参数
|
|
147
|
+
{ path: '/user/{id}', component: User },
|
|
148
|
+
|
|
149
|
+
// 可选参数
|
|
150
|
+
{ path: '/search/{query?}', component: Search },
|
|
151
|
+
|
|
152
|
+
// 带正则约束
|
|
153
|
+
{
|
|
154
|
+
path: '/post/{id}',
|
|
155
|
+
component: Post,
|
|
156
|
+
pattern: { id: /^\d+$/ } // 只匹配数字
|
|
157
|
+
}
|
|
158
|
+
)
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### 嵌套路由
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
const routes = defineRoutes({
|
|
165
|
+
path: '/user',
|
|
166
|
+
component: UserLayout,
|
|
167
|
+
children: [
|
|
168
|
+
{ path: '/user/profile', component: Profile },
|
|
169
|
+
{ path: '/user/settings', component: Settings }
|
|
170
|
+
]
|
|
171
|
+
})
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### 命名路由
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
const routes = defineRoutes({
|
|
178
|
+
path: '/user/{id}',
|
|
179
|
+
name: 'user-detail',
|
|
180
|
+
component: UserDetail
|
|
181
|
+
})
|
|
182
|
+
|
|
183
|
+
// 导航时使用名称
|
|
184
|
+
router.push({ index: 'user-detail', params: { id: '123' } })
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### 重定向
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
const routes = defineRoutes(
|
|
191
|
+
// 字符串重定向
|
|
192
|
+
{ path: '/home', redirect: '/' },
|
|
193
|
+
|
|
194
|
+
// 对象重定向
|
|
195
|
+
{ path: '/old-user/{id}', redirect: { index: 'user-detail' } },
|
|
196
|
+
|
|
197
|
+
// 函数重定向
|
|
20
198
|
{
|
|
21
|
-
path: '/',
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
199
|
+
path: '/search/{query}',
|
|
200
|
+
redirect: (to) => {
|
|
201
|
+
return { index: 'search-results', query: { q: to.params.query } }
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
)
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### 路由元数据
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
const routes = defineRoutes({
|
|
211
|
+
path: '/admin',
|
|
212
|
+
component: Admin,
|
|
213
|
+
meta: {
|
|
214
|
+
requiresAuth: true,
|
|
215
|
+
title: '管理后台'
|
|
216
|
+
}
|
|
217
|
+
})
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### 命名视图
|
|
221
|
+
|
|
222
|
+
```jsx
|
|
223
|
+
const routes = defineRoutes({
|
|
224
|
+
path: '/settings',
|
|
225
|
+
component: {
|
|
226
|
+
default: SettingsMain,
|
|
227
|
+
sidebar: SettingsSidebar
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
// 模板中使用
|
|
232
|
+
<RouterView />;
|
|
233
|
+
<RouterView name="sidebar" />
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### 路由参数注入
|
|
237
|
+
|
|
238
|
+
```typescript
|
|
239
|
+
const routes = defineRoutes(
|
|
240
|
+
// 注入动态参数到组件 props
|
|
241
|
+
{ path: '/user/{id}', component: User, props: true },
|
|
242
|
+
|
|
243
|
+
// 注入静态对象
|
|
244
|
+
{ path: '/about', component: About, props: { showFooter: true } },
|
|
245
|
+
|
|
246
|
+
// 使用函数动态注入
|
|
247
|
+
{
|
|
248
|
+
path: '/search/{query}',
|
|
249
|
+
component: Search,
|
|
250
|
+
props: (route) => ({
|
|
251
|
+
query: route.params.query,
|
|
252
|
+
page: route.query.page
|
|
253
|
+
})
|
|
29
254
|
}
|
|
30
255
|
)
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## 导航方法
|
|
261
|
+
|
|
262
|
+
### push
|
|
263
|
+
|
|
264
|
+
跳转到新路由,添加历史记录。
|
|
265
|
+
|
|
266
|
+
```typescript
|
|
267
|
+
// 路径导航
|
|
268
|
+
router.push({ index: '/user/123' })
|
|
269
|
+
|
|
270
|
+
// 命名导航
|
|
271
|
+
router.push({ index: 'user-detail', params: { id: '123' } })
|
|
272
|
+
|
|
273
|
+
// 带查询参数
|
|
274
|
+
router.push({ index: '/search', query: { q: 'keyword' } })
|
|
275
|
+
|
|
276
|
+
// 带 hash
|
|
277
|
+
router.push({ index: '/about', hash: '#section' })
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### replace
|
|
281
|
+
|
|
282
|
+
替换当前路由,不添加历史记录。
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
router.replace({ index: '/login' })
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### go
|
|
289
|
+
|
|
290
|
+
前进/后退指定步数。
|
|
291
|
+
|
|
292
|
+
```typescript
|
|
293
|
+
router.go(-1) // 后退一步
|
|
294
|
+
router.go(1) // 前进一步
|
|
295
|
+
router.go(2) // 前进两步
|
|
296
|
+
router.go() // 刷新当前页面
|
|
297
|
+
```
|
|
31
298
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
299
|
+
### back / forward
|
|
300
|
+
|
|
301
|
+
后退/前进一步。
|
|
302
|
+
|
|
303
|
+
```typescript
|
|
304
|
+
router.back() // 等同于 router.go(-1)
|
|
305
|
+
router.forward() // 等同于 router.go(1)
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
## 导航守卫
|
|
311
|
+
|
|
312
|
+
### 全局前置守卫
|
|
313
|
+
|
|
314
|
+
在路由跳转前执行,可用于权限验证。
|
|
315
|
+
|
|
316
|
+
```typescript
|
|
317
|
+
const router = createRouter({ routes })
|
|
318
|
+
|
|
319
|
+
router.beforeEach((to, from) => {
|
|
320
|
+
// 需要登录的页面
|
|
321
|
+
if (to.meta.requiresAuth && !isAuthenticated()) {
|
|
322
|
+
return { index: '/login' } // 重定向到登录页
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// 返回 false 取消导航
|
|
326
|
+
// return false
|
|
327
|
+
|
|
328
|
+
// 返回 void 或 true 继续导航
|
|
37
329
|
})
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### 全局后置守卫
|
|
333
|
+
|
|
334
|
+
在路由跳转后执行,可用于更新页面标题等。
|
|
38
335
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
336
|
+
```typescript
|
|
337
|
+
router.afterEach((to, from) => {
|
|
338
|
+
// 更新页面标题
|
|
339
|
+
document.title = to.meta.title || '默认标题'
|
|
340
|
+
})
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
### 路由级守卫
|
|
344
|
+
|
|
345
|
+
```typescript
|
|
346
|
+
const routes = defineRoutes({
|
|
347
|
+
path: '/admin',
|
|
348
|
+
component: Admin,
|
|
349
|
+
beforeEnter: (to, from) => {
|
|
350
|
+
if (!isAdmin()) {
|
|
351
|
+
return { index: '/' }
|
|
352
|
+
}
|
|
353
|
+
},
|
|
354
|
+
afterEnter: (to, from) => {
|
|
355
|
+
console.log('进入管理页面')
|
|
356
|
+
}
|
|
357
|
+
})
|
|
44
358
|
```
|
|
45
359
|
|
|
360
|
+
### 守卫返回值
|
|
361
|
+
|
|
362
|
+
| 返回值 | 说明 |
|
|
363
|
+
|------------------|----------|
|
|
364
|
+
| `true` / `void` | 继续导航 |
|
|
365
|
+
| `false` | 取消导航 |
|
|
366
|
+
| `string` | 重定向到指定路径 |
|
|
367
|
+
| `NavigateTarget` | 重定向到目标路由 |
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
## 组件
|
|
372
|
+
|
|
373
|
+
### RouterView
|
|
374
|
+
|
|
375
|
+
渲染匹配的路由组件。
|
|
376
|
+
|
|
377
|
+
```jsx
|
|
378
|
+
// 基本用法
|
|
379
|
+
<RouterView />
|
|
380
|
+
|
|
381
|
+
// 命名视图
|
|
382
|
+
<RouterView name="sidebar" />
|
|
383
|
+
|
|
384
|
+
// 带过渡效果
|
|
385
|
+
<RouterView>
|
|
386
|
+
{(Component) => (
|
|
387
|
+
<Transition name="fade">
|
|
388
|
+
<Component />
|
|
389
|
+
</Transition>
|
|
390
|
+
)}
|
|
391
|
+
</RouterView>
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
### RouterLink
|
|
395
|
+
|
|
396
|
+
声明式导航链接。
|
|
397
|
+
|
|
398
|
+
```jsx
|
|
399
|
+
// 基本用法
|
|
400
|
+
<RouterLink to="/">首页</RouterLink>
|
|
401
|
+
|
|
402
|
+
// 命名路由
|
|
403
|
+
<RouterLink to={{ index: 'user-detail', params: { id: '123' } }}>
|
|
404
|
+
用户详情
|
|
405
|
+
</RouterLink>
|
|
406
|
+
|
|
407
|
+
// 带查询参数
|
|
408
|
+
<RouterLink to={{ index: '/search', query: { q: 'keyword' } }}>
|
|
409
|
+
搜索
|
|
410
|
+
</RouterLink>
|
|
411
|
+
|
|
412
|
+
// 替换模式
|
|
413
|
+
<RouterLink to="/about" replace>关于</RouterLink>
|
|
414
|
+
|
|
415
|
+
// 激活匹配
|
|
416
|
+
<RouterLink to="/" active="strict">首页</RouterLink>
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
---
|
|
420
|
+
|
|
421
|
+
## 组合式 API
|
|
422
|
+
|
|
423
|
+
### useRouter
|
|
424
|
+
|
|
425
|
+
获取路由器实例。
|
|
426
|
+
|
|
427
|
+
```jsx
|
|
428
|
+
import { useRouter } from 'vitarx-router'
|
|
429
|
+
|
|
430
|
+
export default function Component() {
|
|
431
|
+
const router = useRouter()
|
|
432
|
+
|
|
433
|
+
const handleClick = () => {
|
|
434
|
+
router.push({ index: '/home' })
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
return <button onClick={handleClick}>跳转</button>
|
|
438
|
+
}
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
### useRoute
|
|
442
|
+
|
|
443
|
+
获取当前路由信息。
|
|
444
|
+
|
|
445
|
+
```jsx
|
|
446
|
+
import { useRoute } from 'vitarx-router'
|
|
447
|
+
|
|
448
|
+
export default function UserDetail() {
|
|
449
|
+
const route = useRoute()
|
|
450
|
+
|
|
451
|
+
// 路由参数
|
|
452
|
+
const userId = route.params.id
|
|
453
|
+
|
|
454
|
+
// 查询参数
|
|
455
|
+
const query = route.query
|
|
456
|
+
|
|
457
|
+
// 路由元数据
|
|
458
|
+
const meta = route.meta
|
|
459
|
+
|
|
460
|
+
return <div>用户ID: {userId}</div>
|
|
461
|
+
}
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
---
|
|
465
|
+
|
|
466
|
+
## 路由对象
|
|
467
|
+
|
|
468
|
+
### RouteLocation
|
|
469
|
+
|
|
470
|
+
当前路由信息对象。
|
|
471
|
+
|
|
472
|
+
| 属性 | 类型 | 说明 |
|
|
473
|
+
|------------|--------------------------|-------------------|
|
|
474
|
+
| `path` | `string` | 路由路径 |
|
|
475
|
+
| `fullPath` | `string` | 完整路径(含查询参数和 hash) |
|
|
476
|
+
| `params` | `Record<string, any>` | 路由参数 |
|
|
477
|
+
| `query` | `Record<string, string>` | 查询参数 |
|
|
478
|
+
| `hash` | `string` | URL hash |
|
|
479
|
+
| `name` | `string` | 路由名称 |
|
|
480
|
+
| `meta` | `RouteMetaData` | 路由元数据 |
|
|
481
|
+
| `matched` | `RouteNormalized[]` | 匹配的路由记录 |
|
|
482
|
+
|
|
483
|
+
### NavigateResult
|
|
484
|
+
|
|
485
|
+
导航结果对象。
|
|
486
|
+
|
|
487
|
+
| 属性 | 类型 | 说明 |
|
|
488
|
+
|----------------|-------------------------|-------|
|
|
489
|
+
| `status` | `NavigateStatus` | 导航状态 |
|
|
490
|
+
| `message` | `string` | 状态描述 |
|
|
491
|
+
| `to` | `ReadonlyRouteLocation` | 目标路由 |
|
|
492
|
+
| `from` | `ReadonlyRouteLocation` | 来源路由 |
|
|
493
|
+
| `redirectFrom` | `NavigateTarget` | 重定向来源 |
|
|
494
|
+
|
|
495
|
+
---
|
|
496
|
+
|
|
497
|
+
## 路由选项
|
|
498
|
+
|
|
499
|
+
### RouterOptions
|
|
500
|
+
|
|
501
|
+
| 选项 | 类型 | 默认值 | 说明 |
|
|
502
|
+
|------------------|--------------------------------------|------------|------------|
|
|
503
|
+
| `routes` | `Route[]` | - | 路由配置数组(必填) |
|
|
504
|
+
| `mode` | `'hash' \| 'path' \| 'memory'` | `'hash'` | 路由模式 |
|
|
505
|
+
| `base` | `string` | `'/'` | 基础路径 |
|
|
506
|
+
| `strict` | `boolean` | `false` | 是否区分大小写 |
|
|
507
|
+
| `suffix` | `string \| string[] \| '*' \| false` | `'*'` | URL 后缀匹配 |
|
|
508
|
+
| `defaultSuffix` | `string` | `''` | 默认后缀 |
|
|
509
|
+
| `pattern` | `RegExp` | `/[\w.]+/` | 动态参数默认匹配模式 |
|
|
510
|
+
| `scrollBehavior` | `ScrollBehavior \| Function` | `'auto'` | 滚动行为 |
|
|
511
|
+
| `beforeEach` | `BeforeEnterCallback` | - | 全局前置守卫 |
|
|
512
|
+
| `afterEach` | `AfterEnterCallback` | - | 全局后置守卫 |
|
|
513
|
+
| `missing` | `RouteComponent` | - | 未匹配时渲染的组件 |
|
|
514
|
+
|
|
515
|
+
---
|
|
516
|
+
|
|
517
|
+
## TypeScript 支持
|
|
518
|
+
|
|
519
|
+
### 扩展路由元数据类型
|
|
520
|
+
|
|
521
|
+
```typescript
|
|
522
|
+
// 在全局类型声明文件中
|
|
523
|
+
declare module 'vitarx-router' {
|
|
524
|
+
interface RouteMetaData {
|
|
525
|
+
title?: string
|
|
526
|
+
requiresAuth?: boolean
|
|
527
|
+
icon?: string
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
### 扩展路由索引类型
|
|
533
|
+
|
|
534
|
+
```typescript
|
|
535
|
+
declare module 'vitarx-router' {
|
|
536
|
+
interface RouteIndexMap {
|
|
537
|
+
'user-detail': { params: { id: string } }
|
|
538
|
+
'search': { query: { q: string } }
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
// 使用时会有类型提示
|
|
543
|
+
router.push({ index: 'user-detail', params: { id: '123' } })
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
---
|
|
547
|
+
|
|
548
|
+
## 文件路由
|
|
549
|
+
|
|
550
|
+
配合 Vite 插件实现基于文件系统的路由自动生成。
|
|
551
|
+
|
|
552
|
+
### 安装配置
|
|
553
|
+
|
|
554
|
+
```typescript
|
|
555
|
+
// vite.config.ts
|
|
556
|
+
import VitarxRouter from 'vitarx-router/vite'
|
|
557
|
+
|
|
558
|
+
export default defineConfig({
|
|
559
|
+
plugins: [
|
|
560
|
+
VitarxRouter({
|
|
561
|
+
pagesDir: 'src/pages'
|
|
562
|
+
})
|
|
563
|
+
]
|
|
564
|
+
})
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
### 使用生成的路由
|
|
568
|
+
|
|
569
|
+
```typescript
|
|
570
|
+
import { routes } from 'vitarx-router/auto-routes'
|
|
571
|
+
import { createRouter } from 'vitarx-router'
|
|
572
|
+
|
|
573
|
+
export const router = createRouter({ routes })
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
详细配置请参考 [Vite 插件文档](./src/vite/README.md)。
|
|
577
|
+
|
|
578
|
+
---
|
|
579
|
+
|
|
580
|
+
## API 参考
|
|
581
|
+
|
|
582
|
+
### 助手函数
|
|
583
|
+
|
|
584
|
+
| 函数 | 说明 |
|
|
585
|
+
|---------------------------------------|----------|
|
|
586
|
+
| `createRouter(options)` | 创建路由器实例 |
|
|
587
|
+
| `defineRoutes(...routes)` | 定义路由表 |
|
|
588
|
+
| `defineRoute(route)` | 定义单个路由 |
|
|
589
|
+
| `useRouter()` | 获取路由器实例 |
|
|
590
|
+
| `useRoute()` | 获取当前路由信息 |
|
|
591
|
+
| `hasNavigationStatus(result, status)` | 检查导航状态 |
|
|
592
|
+
|
|
593
|
+
### Router 实例方法
|
|
594
|
+
|
|
595
|
+
| 方法 | 说明 |
|
|
596
|
+
|--------------------|-----------|
|
|
597
|
+
| `push(options)` | 跳转到新路由 |
|
|
598
|
+
| `replace(options)` | 替换当前路由 |
|
|
599
|
+
| `go(delta)` | 前进/后退指定步数 |
|
|
600
|
+
| `back()` | 后退一步 |
|
|
601
|
+
| `forward()` | 前进一步 |
|
|
602
|
+
| `scrollTo(target)` | 滚动到指定位置 |
|
|
603
|
+
| `initialize()` | 初始化路由器 |
|
|
604
|
+
|
|
605
|
+
### Router 实例属性
|
|
606
|
+
|
|
607
|
+
| 属性 | 说明 |
|
|
608
|
+
|------------------|---------------|
|
|
609
|
+
| `route` | 当前路由信息(只读响应式) |
|
|
610
|
+
| `options` | 路由器配置选项 |
|
|
611
|
+
| `mode` | 路由模式 |
|
|
612
|
+
| `isBrowser` | 是否浏览器环境 |
|
|
613
|
+
| `scrollBehavior` | 滚动行为 |
|
|
614
|
+
|
|
615
|
+
---
|
|
616
|
+
|
|
617
|
+
## License
|
|
618
|
+
|
|
619
|
+
MIT
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { ElementView, type ValidChildren, type WithProps } from 'vitarx';
|
|
2
|
+
import { type NavigateResult, type NavigateTarget, type RouteIndex } from '../core/index.js';
|
|
3
|
+
type HttpUrl = `http://${string}` | `https://${string}`;
|
|
4
|
+
type Hash = `#${string}`;
|
|
5
|
+
export interface RouterLinkProps extends WithProps<'a'> {
|
|
6
|
+
/**
|
|
7
|
+
* 要跳转的目标
|
|
8
|
+
*
|
|
9
|
+
* 可以是路由目标对象,也可以是路由索引
|
|
10
|
+
*/
|
|
11
|
+
to: NavigateTarget | RouteIndex | HttpUrl | Hash | `${RouteIndex}${Hash}` | `${RouteIndex}?${string}`;
|
|
12
|
+
/**
|
|
13
|
+
* 子节点插槽
|
|
14
|
+
*/
|
|
15
|
+
children?: ValidChildren;
|
|
16
|
+
/**
|
|
17
|
+
* 是否禁用
|
|
18
|
+
*
|
|
19
|
+
* @default false
|
|
20
|
+
*/
|
|
21
|
+
disabled?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* 激活状态计算
|
|
24
|
+
*
|
|
25
|
+
* 如果启用了激活状态计算,那么当路由匹配到当前路由时,a标签会添加`aria-current="page"`属性,
|
|
26
|
+
*
|
|
27
|
+
* 算法:
|
|
28
|
+
* - 如果路由索引以/开头
|
|
29
|
+
* - 严格匹配`Router.currentRouteLocation.path === to.index`,
|
|
30
|
+
* - 模糊匹配`Router.currentRouteLocation.fullPath.startsWith(to.index)`
|
|
31
|
+
* - 如果路由索引不以/开头,则会匹配`Router.currentRouteLocation.matched[i].name`,仅支持严格匹配
|
|
32
|
+
*
|
|
33
|
+
* 可选值:
|
|
34
|
+
* - none:不计算激活状态
|
|
35
|
+
* - obscure:模糊匹配,只要目标路由的路径以当前路由的路径开头,就认为当前路由处于激活状态
|
|
36
|
+
* - strict:严格匹配,只有目标路由的路径完全匹配当前路由的路径,才认为当前路由处于激活状态
|
|
37
|
+
*
|
|
38
|
+
* @default 'none'
|
|
39
|
+
*/
|
|
40
|
+
active?: 'none' | 'obscure' | 'strict';
|
|
41
|
+
/**
|
|
42
|
+
* 导航回调函数
|
|
43
|
+
*
|
|
44
|
+
* @param {NavigateResult} result - 导航结果
|
|
45
|
+
*/
|
|
46
|
+
callback?: (result: NavigateResult) => void;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* 路由跳转组件
|
|
50
|
+
*
|
|
51
|
+
* 它只是简单的实现了一个a标签,点击后跳转到目标路由,
|
|
52
|
+
* 如果有更高级的定制需求,往往你可以项目中自行编写一个小部件来实现任何你想要的效果。
|
|
53
|
+
*
|
|
54
|
+
* @param {RouterLinkProps} props - 路由跳转组件属性
|
|
55
|
+
* @returns {ElementView<'a'>} - a元素视图
|
|
56
|
+
*/
|
|
57
|
+
export declare function RouterLink(props: RouterLinkProps): ElementView<'a'>;
|
|
58
|
+
export {};
|