befly-vite 1.5.16 → 1.5.17

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 (2) hide show
  1. package/index.browser.js +60 -65
  2. package/package.json +2 -2
package/index.browser.js CHANGED
@@ -8,69 +8,80 @@
8
8
  */
9
9
 
10
10
  /**
11
- * 内部扁平结构:一条“最终路由 path + 选用布局 + 页面组件”。
12
- * @typedef {Object} LayoutConfig
13
- * @property {string} path
14
- * @property {string} layoutName
15
- * @property {any} component
16
- * @property {Record<string, any>=} meta
17
- */
18
-
19
- /**
20
- * 内部实现:根据文件名后缀 _数字 判断使用哪个布局,输出扁平布局配置。
11
+ * 内部实现:根据文件名后缀 _数字 判断使用哪个布局,并直接输出最终路由。
21
12
  *
22
13
  * 注意:该函数仅供 befly-vite 包内部使用,不作为对外 API。
23
14
  *
24
15
  * @param {RouteConfig[]} routes
16
+ * @param {(layoutName: string) => any} resolveLayoutComponent
17
+ * @param {string=} parentPath
25
18
  * @param {string=} inheritLayout
26
- * @returns {LayoutConfig[]}
19
+ * @returns {import('vue-router').RouteRecordRaw[]}
27
20
  */
28
- function buildLayoutConfigs(routes, inheritLayout = "") {
29
- /** @type {LayoutConfig[]} */
21
+ function parseRoutePath(path) {
22
+ const rawPath = String(path || "");
23
+ const match = rawPath.match(/_(\d+)$/);
24
+
25
+ return {
26
+ layoutName: match ? match[1] : "",
27
+ path: match ? rawPath.slice(0, match.index) : rawPath
28
+ };
29
+ }
30
+
31
+ function normalizeRoutePath(path) {
32
+ return String(path || "")
33
+ .split("/")
34
+ .filter(Boolean)
35
+ .map((segment) => {
36
+ if (segment.startsWith(":")) {
37
+ return segment;
38
+ }
39
+
40
+ return segment
41
+ .replace(/_/g, "-")
42
+ .replace(/([a-z0-9])([A-Z])/g, "$1-$2")
43
+ .toLowerCase();
44
+ })
45
+ .join("/");
46
+ }
47
+
48
+ function joinRoutePath(parentPath, childPath) {
49
+ if (!parentPath) {
50
+ return childPath;
51
+ }
52
+
53
+ if (!childPath) {
54
+ return parentPath;
55
+ }
56
+
57
+ return `${parentPath}/${childPath}`;
58
+ }
59
+
60
+ function buildLayoutRoutes(routes, resolveLayoutComponent, parentPath = "", inheritLayout = "") {
61
+ /** @type {import('vue-router').RouteRecordRaw[]} */
30
62
  const result = [];
31
63
 
32
64
  for (const route of routes) {
33
- const currentPath = route.path || "";
34
-
35
- const pathMatch = currentPath.match(/_(\d+)$/);
36
- const currentLayout = pathMatch ? pathMatch[1] : inheritLayout;
65
+ const { layoutName, path } = parseRoutePath(route.path);
66
+ const currentLayout = layoutName || inheritLayout;
67
+ const currentPath = path === "index" ? "" : normalizeRoutePath(path);
68
+ const fullPath = joinRoutePath(parentPath, currentPath);
37
69
 
38
- // 中间节点:递归处理子路由,不包裹布局
39
70
  if (route.children && route.children.length > 0) {
40
- const cleanPath = pathMatch ? currentPath.replace(/_\d+$/, "") : currentPath;
41
- const childConfigs = buildLayoutConfigs(route.children, currentLayout);
42
-
43
- for (const child of childConfigs) {
44
- const mergedPath = cleanPath ? `${cleanPath}/${child.path}`.replace(/\/+/, "/") : child.path;
45
- result.push({
46
- path: mergedPath,
47
- layoutName: child.layoutName,
48
- component: child.component,
49
- meta: child.meta
50
- });
51
- }
71
+ result.push(...buildLayoutRoutes(route.children, resolveLayoutComponent, fullPath, currentLayout));
52
72
  continue;
53
73
  }
54
74
 
55
- // 叶子节点:包裹布局
56
- const lastPart = currentPath;
57
- const match = lastPart.match(/_(\d+)$/);
58
- const layoutName = match ? match[1] : currentLayout || "default";
59
-
60
- let cleanPath = "";
61
- if (lastPart === "index" || (lastPart.startsWith("index_") && match)) {
62
- cleanPath = "";
63
- } else if (match) {
64
- cleanPath = lastPart.replace(/_\d+$/, "");
65
- } else {
66
- cleanPath = lastPart;
67
- }
68
-
69
75
  result.push({
70
- path: cleanPath,
71
- layoutName: layoutName,
72
- component: route.component,
73
- meta: route.meta
76
+ path: fullPath,
77
+ component: resolveLayoutComponent(currentLayout || "default"),
78
+ meta: route.meta,
79
+ children: [
80
+ {
81
+ path: "",
82
+ component: route.component
83
+ }
84
+ ]
74
85
  });
75
86
  }
76
87
 
@@ -100,23 +111,7 @@ export function Layouts(routes, rootRedirectPath, resolveLayoutComponent) {
100
111
 
101
112
  const trimmedRootRedirectPath = typeof rootRedirectPath === "string" ? rootRedirectPath.trim() : "";
102
113
 
103
- const configs = buildLayoutConfigs(routes);
104
-
105
- const layoutRoutes = configs.map((config) => {
106
- const layoutComponent = resolveLayoutComponent(config.layoutName);
107
-
108
- return {
109
- path: config.path,
110
- component: layoutComponent,
111
- meta: config.meta,
112
- children: [
113
- {
114
- path: "",
115
- component: config.component
116
- }
117
- ]
118
- };
119
- });
114
+ const layoutRoutes = buildLayoutRoutes(routes, resolveLayoutComponent);
120
115
 
121
116
  if (trimmedRootRedirectPath && trimmedRootRedirectPath !== "/") {
122
117
  return [
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "befly-vite",
3
- "version": "1.5.16",
4
- "gitHead": "29606d61e67d0e446c4b7df92a5104ed05ac909d",
3
+ "version": "1.5.17",
4
+ "gitHead": "7e5f2dee776d284ec29cec8aaf9ebc0acf24385d",
5
5
  "private": false,
6
6
  "description": "Befly Vite 配置预设和插件集合",
7
7
  "keywords": [