ljr-cli 1.0.8 → 1.0.10
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/bin/commands/demo1.js +1 -1
- package/bin/commands/init.js +3 -1
- package/bin/commands/sync.js +120 -16
- package/bin/templates/vue2.7.16/README.md +15 -13
- package/bin/templates/vue2.7.16/public/index.html +5 -5
- package/bin/templates/vue3.5.25-2025.12.4/.vscode/settings.json +1 -0
- package/bin/templates/vue3.5.25-2025.12.4/README.md +28 -17
- package/bin/templates/vue3.5.25-2025.12.4/auto-imports.d.ts +229 -0
- package/bin/templates/vue3.5.25-2025.12.4/components.d.ts +49 -0
- package/bin/templates/vue3.5.25-2025.12.4/eslint.config.ts +1 -0
- package/bin/templates/vue3.5.25-2025.12.4/index.html +2 -2
- package/bin/templates/vue3.5.25-2025.12.4/package.json +3 -1
- package/bin/templates/vue3.5.25-2025.12.4/pnpm-lock.yaml +480 -11
- package/bin/templates/vue3.5.25-2025.12.4/src/assets/images/login_bg.jpg +0 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/assets/images/login_bg_black.jpg +0 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/assets/images/sc_login_icon.png +0 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/boot/el-icon.ts +9 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/boot/index.ts +2 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/boot/pinia.ts +8 -3
- package/bin/templates/vue3.5.25-2025.12.4/src/boot/style.ts +2 -1
- package/bin/templates/vue3.5.25-2025.12.4/src/components/layout/header.ts +97 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/components/layout/header.vue +37 -13
- package/bin/templates/vue3.5.25-2025.12.4/src/components/layout/left-right.vue +3 -7
- package/bin/templates/vue3.5.25-2025.12.4/src/components/layout/menu.ts +19 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/components/layout/menu.vue +89 -5
- package/bin/templates/vue3.5.25-2025.12.4/src/components/layout/up-down.vue +24 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/components/login/change-password.vue +111 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/components/login/user-login.vue +61 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/css/base.css +204 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/css/global.css +1596 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/css/index.css +3 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/css/theme.css +61 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/dialogs/device/index.ts +1 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/dialogs/dialog.vue +66 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/dialogs/helper.ts +90 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/dialogs/index.ts +2 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/dialogs/template.ts +41 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/dialogs/template.vue +29 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/dialogs/user-info/index.ts +31 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/dialogs/user-info/layout.ts +47 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/dialogs/user-info/layout.vue +51 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/dialogs/user-info/notification.ts +27 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/dialogs/user-info/notification.vue +29 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/dialogs/user-info/permission.ts +22 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/dialogs/user-info/permission.vue +23 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/directive/rememberScrollPosition.ts +1 -1
- package/bin/templates/vue3.5.25-2025.12.4/src/enums/device.ts +42 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/enums/index.ts +2 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/enums/status.ts +23 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/pages/index/permission/role.ts +40 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/pages/index/permission/role.vue +39 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/pages/index/permission/user.vue +10 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/pages/index/template/base-info.vue +5 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/pages/index/template/base-info2.vue +5 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/pages/index/template/list.ts +40 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/pages/index/template/list.vue +39 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/pages/index/template/store.vue +89 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/pages/index.vue +7 -2
- package/bin/templates/vue3.5.25-2025.12.4/src/pages/login.vue +34 -64
- package/bin/templates/vue3.5.25-2025.12.4/src/stores/account(/351/200/211/351/241/271/345/274/217api/345/206/231/346/263/225/347/244/272/344/276/213).ts +49 -0
- package/bin/templates/vue3.5.25-2025.12.4/src/stores/account.ts +46 -28
- package/bin/templates/vue3.5.25-2025.12.4/src/stores/dd.ts +85 -29
- package/bin/templates/vue3.5.25-2025.12.4/src/stores/layout.ts +99 -21
- package/bin/templates/vue3.5.25-2025.12.4/typed-router.d.ts +90 -0
- package/bin/templates/vue3.5.25-2025.12.4/uno.config.ts +53 -0
- package/bin/templates/vue3.5.25-2025.12.4/vite.config.ts +12 -1
- package/package.json +2 -2
- package/bin/templates/vue3.5.25-2025.12.4/src/stores//347/273/204/345/220/210/345/274/217pinia/345/206/231/346/263/225(/344/273/245account/344/270/272/344/276/213).ts +0 -28
- /package/bin/templates/vue3.5.25-2025.12.4/{public → src/assets}/favicon.svg +0 -0
package/bin/commands/demo1.js
CHANGED
package/bin/commands/init.js
CHANGED
|
@@ -29,7 +29,9 @@ export default function registerInit(program, { currentRunningDirPath, cwdPath,
|
|
|
29
29
|
placeholder: "项目名称",
|
|
30
30
|
validate: (value) => {
|
|
31
31
|
if (!value.trim().length) return "请输入项目名称"
|
|
32
|
-
if (
|
|
32
|
+
if (!/^[a-zA-Z_][a-zA-Z0-9_\-]*$/.test(value)) {
|
|
33
|
+
return "英文开头或下划线开头,且只能包含英文、数字、下划线或中划线"
|
|
34
|
+
}
|
|
33
35
|
},
|
|
34
36
|
}),
|
|
35
37
|
templateName: () =>
|
package/bin/commands/sync.js
CHANGED
|
@@ -10,28 +10,132 @@ export default function registerSync(program, { currentRunningDirPath, cwdPath,
|
|
|
10
10
|
.action(async () => {
|
|
11
11
|
prompts.intro(gradientString("开始同步"))
|
|
12
12
|
|
|
13
|
+
const destPath = await prompts.text({
|
|
14
|
+
message: "输出的文件夹路径:",
|
|
15
|
+
placeholder: "输出的文件夹路径",
|
|
16
|
+
initialValue: "src",
|
|
17
|
+
validate: (value) => {
|
|
18
|
+
if (!value.trim().length) return "请输入输出的文件夹路径"
|
|
19
|
+
},
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
/** 选择同步的文件夹 */
|
|
23
|
+
const syncFolder = await prompts.multiselect({
|
|
24
|
+
message: "请选择需要同步的文件夹",
|
|
25
|
+
options: [
|
|
26
|
+
{ label: "css", value: "css" },
|
|
27
|
+
{ label: "less", value: "less" },
|
|
28
|
+
{ label: "utils", value: "utils" },
|
|
29
|
+
],
|
|
30
|
+
required: true,
|
|
31
|
+
initialValues: ["css", "utils"],
|
|
32
|
+
})
|
|
33
|
+
if (prompts.isCancel(syncFolder)) {
|
|
34
|
+
prompts.cancel("取消操作!")
|
|
35
|
+
process.exit(0)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** 选择同步的css文件 */
|
|
39
|
+
let cssFiles = []
|
|
40
|
+
if (syncFolder.includes("css")) {
|
|
41
|
+
cssFiles = await prompts.multiselect({
|
|
42
|
+
message: `请选择需要同步的css文件${gradientString("(未选择的情况下,同步整个文件夹)", ["red", "red"])}`,
|
|
43
|
+
options: [
|
|
44
|
+
{ label: "index.css", value: "index.css" },
|
|
45
|
+
{ label: "base.css", value: "base.css" },
|
|
46
|
+
{ label: "theme.css", value: "theme.css" },
|
|
47
|
+
{ label: "global.css", value: "global.css" },
|
|
48
|
+
],
|
|
49
|
+
required: false,
|
|
50
|
+
initialValues: ["index.css", "base.css", "theme.css", "global.css"],
|
|
51
|
+
})
|
|
52
|
+
if (prompts.isCancel(syncFolder)) {
|
|
53
|
+
prompts.cancel("取消操作!")
|
|
54
|
+
process.exit(0)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** 选择同步的util文件 */
|
|
59
|
+
let utilFiles = []
|
|
60
|
+
if (syncFolder.includes("utils")) {
|
|
61
|
+
utilFiles = await prompts.multiselect({
|
|
62
|
+
message: `请选择需要同步的util文件${gradientString("(未选择的情况下,同步整个文件夹)", ["red", "red"])}`,
|
|
63
|
+
options: [
|
|
64
|
+
{ label: "arr.js", value: "arr.js" },
|
|
65
|
+
{ label: "city.js", value: "city.js" },
|
|
66
|
+
{ label: "date.js", value: "date.js" },
|
|
67
|
+
{ label: "file.ts", value: "file.ts" },
|
|
68
|
+
{ label: "file.js", value: "file.js" },
|
|
69
|
+
{ label: "index.js", value: "index.js" },
|
|
70
|
+
],
|
|
71
|
+
required: false,
|
|
72
|
+
initialValues: ["arr.js", "city.js", "date.js", "file.js", "index.js"],
|
|
73
|
+
})
|
|
74
|
+
if (prompts.isCancel(syncFolder)) {
|
|
75
|
+
prompts.cancel("取消操作!")
|
|
76
|
+
process.exit(0)
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
13
80
|
try {
|
|
81
|
+
// 模块路径
|
|
14
82
|
const moduleBase = path.join(currentRunningDirPath, "../node_modules/l-global")
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
83
|
+
// 输出路径
|
|
84
|
+
const destBase = path.join(cwdPath, destPath)
|
|
85
|
+
|
|
86
|
+
const s = prompts.spinner({ indicator: "timer" })
|
|
87
|
+
|
|
88
|
+
// 通用复制函数:若 selectedFiles 有值,则只复制这些文件(文件名包含扩展名),否则复制整个文件夹
|
|
89
|
+
const copyFolderOrFiles = (moduleBasePath, folderName, destBasePath, selectedFiles = []) => {
|
|
90
|
+
const folderSrc = path.join(moduleBasePath, folderName)
|
|
91
|
+
const folderDest = path.join(destBasePath, folderName)
|
|
92
|
+
|
|
93
|
+
// 如果选中了具体文件,逐个复制
|
|
94
|
+
if (selectedFiles && selectedFiles.length) {
|
|
95
|
+
for (const fname of selectedFiles) {
|
|
96
|
+
const srcFile = path.join(folderSrc, fname)
|
|
97
|
+
const destFile = path.join(folderDest, fname)
|
|
98
|
+
s.start(`复制 ${folderName}/${fname} ...`)
|
|
99
|
+
if (!existsSync(srcFile)) {
|
|
100
|
+
s.stop()
|
|
101
|
+
throw new Error(`未找到文件:${srcFile}`)
|
|
102
|
+
}
|
|
103
|
+
// 确保目标目录存在,copySync 会自动创建父目录
|
|
104
|
+
copySync(srcFile, destFile, { overwrite: true })
|
|
105
|
+
s.stop(`已复制:l-global/${folderName}/${fname} -> src/${folderName}/${fname}`)
|
|
106
|
+
}
|
|
107
|
+
return
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// 否则复制整个文件夹
|
|
111
|
+
s.start(`复制 ${folderName} 文件夹...`)
|
|
112
|
+
if (!existsSync(folderSrc)) {
|
|
113
|
+
s.stop()
|
|
114
|
+
throw new Error(`未找到 l-global/${folderName}:${folderSrc}`)
|
|
115
|
+
}
|
|
116
|
+
copySync(folderSrc, folderDest, { recursive: true, overwrite: true })
|
|
117
|
+
s.stop(`已复制:l-global/${folderName} -> src/${folderName}`)
|
|
24
118
|
}
|
|
25
119
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
120
|
+
// 输出的文件夹
|
|
121
|
+
if (syncFolder.length) {
|
|
122
|
+
for (const e of syncFolder) {
|
|
123
|
+
if (e === "css") {
|
|
124
|
+
// 使用通用函数:传入 cssFiles(可能为空)
|
|
125
|
+
copyFolderOrFiles(moduleBase, "css", destBase, cssFiles)
|
|
126
|
+
continue
|
|
127
|
+
}
|
|
128
|
+
if (e === "utils") {
|
|
129
|
+
// 使用通用函数:传入 utilFiles(可能为空)
|
|
130
|
+
copyFolderOrFiles(moduleBase, "utils", destBase, utilFiles)
|
|
131
|
+
continue
|
|
132
|
+
}
|
|
133
|
+
// less / utils 等按整体复制
|
|
134
|
+
copyFolderOrFiles(moduleBase, e, destBase)
|
|
135
|
+
}
|
|
31
136
|
}
|
|
32
137
|
} catch (err) {
|
|
33
|
-
|
|
34
|
-
prompts.cancel("同步失败")
|
|
138
|
+
prompts.cancel(`同步失败:${err}`)
|
|
35
139
|
process.exit(1)
|
|
36
140
|
}
|
|
37
141
|
|
|
@@ -44,28 +44,30 @@ pnpm install
|
|
|
44
44
|
### 项目运行
|
|
45
45
|
|
|
46
46
|
```sh
|
|
47
|
-
pnpm
|
|
47
|
+
pnpm dev || pnpm serve
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
### 项目打包
|
|
51
51
|
|
|
52
52
|
```sh
|
|
53
|
-
pnpm
|
|
53
|
+
pnpm build
|
|
54
54
|
```
|
|
55
55
|
|
|
56
56
|
### 检查和修复文件
|
|
57
57
|
|
|
58
58
|
```sh
|
|
59
|
-
pnpm
|
|
59
|
+
pnpm lint
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
| 类别 | 推荐命名方式 | 示例
|
|
65
|
-
| ------------------ | ----------------------------------------------- |
|
|
66
|
-
| 通用 | kebab-case | package-lock.json
|
|
67
|
-
|
|
|
68
|
-
|
|
|
69
|
-
|
|
|
70
|
-
|
|
|
71
|
-
|
|
|
62
|
+
## 命名规范
|
|
63
|
+
|
|
64
|
+
| 类别 | 推荐命名方式 | 示例 | 关键点/例外情况 |
|
|
65
|
+
| ------------------ | ----------------------------------------------- | -------------------------- | ---------------------- |
|
|
66
|
+
| 通用 | kebab-case | package-lock.json | 没有特别说明尽量用这个 |
|
|
67
|
+
| 路由名称 | kebab-case | user-info | 最通用、最推荐路径命名 |
|
|
68
|
+
| Vue 组件里的组件名 | kebab-case | user-info.vue | |
|
|
69
|
+
| Vue 组件里的 Props | 在声明时使用 camelCase,在模板中使用 kebab-case | | |
|
|
70
|
+
| 方法 / 函数 / 变量 | camelCase | getUserInfo | |
|
|
71
|
+
| 构造函数 / 类 | PascalCase | UserInfo | |
|
|
72
|
+
| 常量 | UPPER_SNAKE_CASE(全大写 + 下划线分隔) | const BASE_API_URL = "xxx" | |
|
|
73
|
+
| 私有属性 / 方法 | \_camelCase(下划线开头 + 小驼峰) | \_userInfo | |
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
|
-
<html lang="">
|
|
2
|
+
<html lang="zh">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="utf-8" />
|
|
5
5
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<noscript>
|
|
12
|
-
<strong
|
|
13
|
-
|
|
14
|
-
enable it to continue
|
|
15
|
-
>
|
|
12
|
+
<strong>
|
|
13
|
+
We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please
|
|
14
|
+
enable it to continue.
|
|
15
|
+
</strong>
|
|
16
16
|
</noscript>
|
|
17
17
|
<div id="app"></div>
|
|
18
18
|
<!-- built files will be auto injected -->
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"explorer.fileNesting.enabled": true,
|
|
3
3
|
"explorer.fileNesting.patterns": {
|
|
4
|
+
"*.vue": "$(capture).ts, $(capture).*.ts, $(capture).*.js, $(capture).css, $(capture).scss, $(capture).less",
|
|
4
5
|
"tsconfig.json": "tsconfig.*.json, env.d.ts",
|
|
5
6
|
"vite.config.*": "jsconfig*, vitest.config.*, cypress.config.*, playwright.config.*",
|
|
6
7
|
"package.json": "*.env, .env.*, env.d.ts, package-lock.json, pnpm*, .yarnrc*, yarn*, .eslint*, eslint*, .oxlint*, oxlint*, .prettier*, prettier*, .editorconfig, .gitignore, .gitattributes, index.html, .browserslistrc, babel.config.js, jsconfig.json, auto-imports.d.ts, components.d.ts, typed-router.d.ts"
|
|
@@ -29,34 +29,35 @@ pnpm install
|
|
|
29
29
|
### 编译和热重载开发
|
|
30
30
|
|
|
31
31
|
```sh
|
|
32
|
-
pnpm
|
|
32
|
+
pnpm dev || pnpm serve
|
|
33
33
|
```
|
|
34
34
|
|
|
35
35
|
### 为生产进行类型检查、编译和最小化
|
|
36
36
|
|
|
37
37
|
```sh
|
|
38
|
-
pnpm
|
|
38
|
+
pnpm build
|
|
39
39
|
```
|
|
40
40
|
|
|
41
41
|
### eslint检查
|
|
42
42
|
|
|
43
43
|
```sh
|
|
44
|
-
pnpm
|
|
44
|
+
pnpm lint
|
|
45
45
|
```
|
|
46
46
|
|
|
47
47
|
### prettier格式化
|
|
48
48
|
|
|
49
49
|
```sh
|
|
50
|
-
pnpm
|
|
50
|
+
pnpm format
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
-
#
|
|
53
|
+
# 样式
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
全局 `@/css/index.css` 里面包含了 `theme.css`、`base.css`、`global.css`
|
|
56
|
+
集成 `unocss` 原子化css
|
|
56
57
|
|
|
57
58
|
# 自动导入
|
|
58
59
|
|
|
59
|
-
使用 `unplugin-auto-import` 插件自动导入vue
|
|
60
|
+
使用 `unplugin-auto-import` 插件自动导入 `vue`、`vue-route`、`pinia`、`vueuse`
|
|
60
61
|
使用 `unplugin-auto-import`、`unplugin-vue-components` 插件按需导入element-plus组件
|
|
61
62
|
|
|
62
63
|
# 路由
|
|
@@ -65,12 +66,21 @@ pnpm run format
|
|
|
65
66
|
加入页面过渡动画
|
|
66
67
|
封装了全局登录判断的路由卫士
|
|
67
68
|
|
|
69
|
+
# 左侧菜单
|
|
70
|
+
|
|
71
|
+
未整理
|
|
72
|
+
|
|
73
|
+
# 函数式弹窗
|
|
74
|
+
|
|
75
|
+
未整理
|
|
76
|
+
|
|
68
77
|
# store仓库
|
|
69
78
|
|
|
70
79
|
使用 `pinia-plugin-persistedstate` 做持久化,默认全部 store 都持久化
|
|
71
80
|
持久化储存的 `key` 默认加上 `pinia` 前缀
|
|
72
81
|
默认都存到 `sessionStorage` ,account 的 store 默认改成 `localStorage` 存储
|
|
73
82
|
如果需要关闭持久化,为单个 store 配置
|
|
83
|
+
此项目统一采用组合式 `pinia` 写法,选项式 `pinia` 写法也有示例,请自行选择
|
|
74
84
|
|
|
75
85
|
# 布局
|
|
76
86
|
|
|
@@ -78,7 +88,6 @@ pnpm run format
|
|
|
78
88
|
|
|
79
89
|
- 上下布局:顶部信息,下左菜单,下右页面
|
|
80
90
|
- 左右布局:左侧菜单,右上顶部信息,右下页面
|
|
81
|
-
- 全屏页面(隐藏顶部信息和菜单):只有页面,没有顶部信息和菜单,可通过快捷键退出全屏页面
|
|
82
91
|
|
|
83
92
|
# 其他
|
|
84
93
|
|
|
@@ -109,16 +118,18 @@ axios 封装
|
|
|
109
118
|
├── stores # stores
|
|
110
119
|
├── views # 页面
|
|
111
120
|
├── package.json
|
|
112
|
-
├──
|
|
121
|
+
├── pnpm-lock.yaml
|
|
113
122
|
```
|
|
114
123
|
|
|
115
124
|
## 命名规范
|
|
116
125
|
|
|
117
|
-
| 类别 | 推荐命名方式 | 示例
|
|
118
|
-
| ------------------ | ----------------------------------------------- |
|
|
119
|
-
| 通用 | kebab-case | package-lock.json
|
|
120
|
-
|
|
|
121
|
-
|
|
|
122
|
-
|
|
|
123
|
-
|
|
|
124
|
-
|
|
|
126
|
+
| 类别 | 推荐命名方式 | 示例 | 关键点/例外情况 |
|
|
127
|
+
| ------------------ | ----------------------------------------------- | -------------------------- | ---------------------- |
|
|
128
|
+
| 通用 | kebab-case | package-lock.json | 没有特别说明尽量用这个 |
|
|
129
|
+
| 路由名称 | kebab-case | user-info | 最通用、最推荐路径命名 |
|
|
130
|
+
| Vue 组件里的组件名 | kebab-case | user-info.vue | |
|
|
131
|
+
| Vue 组件里的 Props | 在声明时使用 camelCase,在模板中使用 kebab-case | | |
|
|
132
|
+
| 方法 / 函数 / 变量 | camelCase | getUserInfo | |
|
|
133
|
+
| 构造函数 / 类 | PascalCase | UserInfo | |
|
|
134
|
+
| 常量 | UPPER_SNAKE_CASE(全大写 + 下划线分隔) | const BASE_API_URL = "xxx" | |
|
|
135
|
+
| 私有属性 / 方法 | \_camelCase(下划线开头 + 小驼峰) | \_userInfo | |
|