vitarx-router 4.0.0-beta.13 → 4.0.0-beta.14
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/dist/components/RouterView.js +5 -4
- package/dist/core/common/constant.d.ts +5 -6
- package/dist/core/common/constant.js +5 -6
- package/dist/core/router/web.js +6 -1
- package/dist/file-router/index.js +1 -1
- package/dist/file-router/parser/parsePage.d.ts +10 -2
- package/dist/file-router/parser/parsePage.js +20 -28
- package/dist/file-router/types/options.d.ts +5 -2
- package/package.json +1 -1
|
@@ -12,7 +12,7 @@ import { __ROUTER_VIEW_DEPTH_KEY__, useRouter } from '../core/index.js';
|
|
|
12
12
|
* @returns {View} 返回渲染的视图
|
|
13
13
|
*/
|
|
14
14
|
export function RouterView(props) {
|
|
15
|
-
const { children
|
|
15
|
+
const { children } = props;
|
|
16
16
|
// 获取路由实例
|
|
17
17
|
const router = useRouter();
|
|
18
18
|
// 获取父级 index
|
|
@@ -20,6 +20,7 @@ export function RouterView(props) {
|
|
|
20
20
|
const index = parentIndex + 1; // 计算当前视图的索引
|
|
21
21
|
provide(__ROUTER_VIEW_DEPTH_KEY__, index); // 向子组件提供当前索引
|
|
22
22
|
// 匹配的路由线路
|
|
23
|
+
const viewName = computed(() => props.name || 'default');
|
|
23
24
|
const matchedRoute = computed(() => {
|
|
24
25
|
return router.route.matched[index] ?? null;
|
|
25
26
|
});
|
|
@@ -28,8 +29,7 @@ export function RouterView(props) {
|
|
|
28
29
|
const currentRoute = matchedRoute.value;
|
|
29
30
|
if (!currentRoute)
|
|
30
31
|
return null;
|
|
31
|
-
|
|
32
|
-
let injectProps = currentRoute.props?.[name] ?? router.config.props ?? false;
|
|
32
|
+
let injectProps = currentRoute.props?.[viewName.value] ?? router.config.props ?? false;
|
|
33
33
|
if (injectProps === false)
|
|
34
34
|
return null; // 如果属性为 false,返回null
|
|
35
35
|
if (injectProps === true && currentRoute.pattern) {
|
|
@@ -52,7 +52,7 @@ export function RouterView(props) {
|
|
|
52
52
|
const route = matchedRoute.value; // 获取匹配的路由记录
|
|
53
53
|
if (!route)
|
|
54
54
|
return null;
|
|
55
|
-
return route.component?.[
|
|
55
|
+
return route.component?.[viewName.value] ?? null;
|
|
56
56
|
});
|
|
57
57
|
// 如果传入了 children 函数,则调用并返回其结果
|
|
58
58
|
if (isFunction(children)) {
|
|
@@ -61,6 +61,7 @@ export function RouterView(props) {
|
|
|
61
61
|
}
|
|
62
62
|
catch (e) {
|
|
63
63
|
logger.error('[RouterView] Error occurred while executing children function', e);
|
|
64
|
+
return createCommentView(`router-view:error`);
|
|
64
65
|
}
|
|
65
66
|
}
|
|
66
67
|
let lastView = null;
|
|
@@ -2,12 +2,11 @@
|
|
|
2
2
|
* 导航状态
|
|
3
3
|
*
|
|
4
4
|
* 枚举值:
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* 5. exception: 捕获到异常
|
|
5
|
+
* 1. success: 导航成功
|
|
6
|
+
* 2. aborted: 导航被阻止
|
|
7
|
+
* 4. cancelled: 导航被取消
|
|
8
|
+
* 8. duplicated: 重复导航
|
|
9
|
+
* 16. notfound: 路由未匹配
|
|
11
10
|
*/
|
|
12
11
|
export declare enum NavState {
|
|
13
12
|
/**
|
|
@@ -2,12 +2,11 @@
|
|
|
2
2
|
* 导航状态
|
|
3
3
|
*
|
|
4
4
|
* 枚举值:
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* 5. exception: 捕获到异常
|
|
5
|
+
* 1. success: 导航成功
|
|
6
|
+
* 2. aborted: 导航被阻止
|
|
7
|
+
* 4. cancelled: 导航被取消
|
|
8
|
+
* 8. duplicated: 重复导航
|
|
9
|
+
* 16. notfound: 路由未匹配
|
|
11
10
|
*/
|
|
12
11
|
export var NavState;
|
|
13
12
|
(function (NavState) {
|
package/dist/core/router/web.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isString, logger } from 'vitarx';
|
|
2
|
+
import { NavState } from '../common/constant.js';
|
|
2
3
|
import { parseHashContent } from '../common/utils.js';
|
|
3
4
|
import { normalizePath, parseQuery } from '../shared/utils.js';
|
|
4
5
|
import { Router } from './router.js';
|
|
@@ -49,7 +50,11 @@ export class WebRouter extends Router {
|
|
|
49
50
|
}
|
|
50
51
|
});
|
|
51
52
|
// 初始化路由
|
|
52
|
-
this.replace(this.urlToNavigateTarget()).then(
|
|
53
|
+
this.replace(this.urlToNavigateTarget()).then(res => {
|
|
54
|
+
if (res.state !== NavState.success) {
|
|
55
|
+
logger.error(`[Router] Initialization failed: ${res.message}`, res);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
53
58
|
// 初始化时监听 popstate 事件,处理历史记录返回时的路由恢复
|
|
54
59
|
window.addEventListener('popstate', this.onPopState);
|
|
55
60
|
if (this.config.mode === 'hash') {
|
|
@@ -194,7 +194,7 @@ export class FileRouter {
|
|
|
194
194
|
*/
|
|
195
195
|
processFile(filePath, page, pageMapping, parent) {
|
|
196
196
|
// 分离出路由 path 和视图命名
|
|
197
|
-
const { routePath, viewName
|
|
197
|
+
const { routePath, viewName } = parseRoutePath(filePath, this.config.pathParser);
|
|
198
198
|
const fileType = this.getPageType(filePath, routePath, page);
|
|
199
199
|
if (fileType === 'ignore')
|
|
200
200
|
return null;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PathParser
|
|
1
|
+
import type { PathParser } from '../types/index.js';
|
|
2
2
|
/**
|
|
3
3
|
* 路径解析错误类
|
|
4
4
|
*
|
|
@@ -22,6 +22,13 @@ export declare class PathParseError extends TypeError {
|
|
|
22
22
|
*/
|
|
23
23
|
toString(): string;
|
|
24
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* 解析结果接口
|
|
27
|
+
*/
|
|
28
|
+
interface ParseResult {
|
|
29
|
+
routePath: string;
|
|
30
|
+
viewName: string;
|
|
31
|
+
}
|
|
25
32
|
/**
|
|
26
33
|
* 解析路由路径和视图名称
|
|
27
34
|
*
|
|
@@ -32,4 +39,5 @@ export declare class PathParseError extends TypeError {
|
|
|
32
39
|
* @returns 路由路径和视图名称
|
|
33
40
|
* @throws {PathParseError} 当路径解析失败时抛出
|
|
34
41
|
*/
|
|
35
|
-
export declare function parseRoutePath(filePath: string, parser?: PathParser):
|
|
42
|
+
export declare function parseRoutePath(filePath: string, parser?: PathParser): ParseResult;
|
|
43
|
+
export {};
|
|
@@ -74,10 +74,10 @@ export class PathParseError extends TypeError {
|
|
|
74
74
|
export function parseRoutePath(filePath, parser) {
|
|
75
75
|
const { basename } = extractFileInfo(filePath);
|
|
76
76
|
if (!parser) {
|
|
77
|
-
return
|
|
77
|
+
return defaultPathParser(basename);
|
|
78
78
|
}
|
|
79
79
|
const result = parser(basename, filePath);
|
|
80
|
-
return
|
|
80
|
+
return parseCustomResult(result, filePath);
|
|
81
81
|
}
|
|
82
82
|
/**
|
|
83
83
|
* 提取文件信息
|
|
@@ -96,24 +96,32 @@ function extractFileInfo(filePath) {
|
|
|
96
96
|
* @param basename - 文件基本名称
|
|
97
97
|
* @returns 解析结果
|
|
98
98
|
*/
|
|
99
|
-
function
|
|
100
|
-
const [
|
|
99
|
+
function defaultPathParser(basename) {
|
|
100
|
+
const [rawPath, viewName] = basename.split('@', 2);
|
|
101
|
+
const routePath = normalizeRoutePath(rawPath);
|
|
102
|
+
if (!routePath) {
|
|
103
|
+
throw new PathParseError('pathParser returned empty routePath', {
|
|
104
|
+
filePath: basename,
|
|
105
|
+
originalValue: rawPath,
|
|
106
|
+
field: 'routePath'
|
|
107
|
+
});
|
|
108
|
+
}
|
|
101
109
|
return {
|
|
102
110
|
routePath,
|
|
103
111
|
viewName: viewName || 'default'
|
|
104
112
|
};
|
|
105
113
|
}
|
|
106
114
|
/**
|
|
107
|
-
*
|
|
115
|
+
* 解析自定义解析器结果
|
|
108
116
|
*
|
|
109
117
|
* @param result - 解析器返回的结果
|
|
110
118
|
* @param filePath - 文件路径(用于错误上下文)
|
|
111
119
|
* @returns 解析结果
|
|
112
120
|
* @throws {PathParseError} 当结果无效时抛出
|
|
113
121
|
*/
|
|
114
|
-
function
|
|
122
|
+
function parseCustomResult(result, filePath) {
|
|
115
123
|
if (typeof result === 'string') {
|
|
116
|
-
return
|
|
124
|
+
return defaultPathParser(result);
|
|
117
125
|
}
|
|
118
126
|
if (result && typeof result === 'object' && !Array.isArray(result)) {
|
|
119
127
|
return parseObjectResult(result, filePath);
|
|
@@ -124,25 +132,6 @@ function parseCustomRouteResult(result, filePath) {
|
|
|
124
132
|
field: 'result'
|
|
125
133
|
});
|
|
126
134
|
}
|
|
127
|
-
/**
|
|
128
|
-
* 解析字符串类型的结果
|
|
129
|
-
*
|
|
130
|
-
* @param result - 字符串结果
|
|
131
|
-
* @param filePath - 文件路径
|
|
132
|
-
* @returns 解析结果
|
|
133
|
-
* @throws {PathParseError} 当路径无效时抛出
|
|
134
|
-
*/
|
|
135
|
-
function parseStringResult(result, filePath) {
|
|
136
|
-
const routePath = normalizeRoutePath(result);
|
|
137
|
-
if (!routePath) {
|
|
138
|
-
throw new PathParseError('pathParser returned empty routePath', {
|
|
139
|
-
filePath,
|
|
140
|
-
originalValue: result,
|
|
141
|
-
field: 'routePath'
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
return { routePath, viewName: 'default' };
|
|
145
|
-
}
|
|
146
135
|
/**
|
|
147
136
|
* 解析对象类型的结果
|
|
148
137
|
*
|
|
@@ -210,11 +199,14 @@ function validateViewName(viewName, filePath) {
|
|
|
210
199
|
/**
|
|
211
200
|
* 标准化路由路径
|
|
212
201
|
*
|
|
213
|
-
*
|
|
202
|
+
* 去除路径首尾空白和首尾的斜杠,将 . # 等不利于 URL 的字符替换为 -。
|
|
214
203
|
*
|
|
215
204
|
* @param routePath - 原始路由路径
|
|
216
205
|
* @returns 标准化后的路由路径
|
|
217
206
|
*/
|
|
218
207
|
function normalizeRoutePath(routePath) {
|
|
219
|
-
return routePath
|
|
208
|
+
return routePath
|
|
209
|
+
.trim()
|
|
210
|
+
.replace(/^\/+|\/+$/g, '')
|
|
211
|
+
.replace(/[.#]/g, '-');
|
|
220
212
|
}
|
|
@@ -52,11 +52,14 @@ export type PathStrategy = 'kebab' | 'lowercase' | 'raw';
|
|
|
52
52
|
export type PageSource = string | PageDirOptions;
|
|
53
53
|
/**
|
|
54
54
|
* 路径解析结果
|
|
55
|
+
*
|
|
56
|
+
* - string: 文件名称,交由内置默认的pathParser继续处理。
|
|
57
|
+
* - `{ routePath: string, viewName?: string }`: 路径和视图名称
|
|
55
58
|
*/
|
|
56
59
|
export type PathParseResult = string | {
|
|
57
|
-
/** 解析后的路径 */
|
|
60
|
+
/** 解析后的路径 如:home.jsx -> 'home' */
|
|
58
61
|
routePath: string;
|
|
59
|
-
/** 视图名称 */
|
|
62
|
+
/** 视图名称 如:home.nav.jsx -> 'nav' */
|
|
60
63
|
viewName?: string;
|
|
61
64
|
};
|
|
62
65
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vitarx-router",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.14",
|
|
4
4
|
"description": "Official routing solution for Vitarx framework with declarative routing, navigation guards, dynamic routes, file-based routing with HMR, and full TypeScript support.",
|
|
5
5
|
"author": "ZhuChonglin <8210856@qq.com>",
|
|
6
6
|
"license": "MIT",
|