cdspec 0.1.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.
Files changed (73) hide show
  1. package/AGENTS.md +14 -0
  2. package/CLAUDE.md +10 -0
  3. package/README.md +55 -0
  4. package/cdspec.config.yaml +34 -0
  5. package/dist/cli.js +94 -0
  6. package/dist/config/default.js +48 -0
  7. package/dist/config/loader.js +30 -0
  8. package/dist/config/path.js +11 -0
  9. package/dist/config/types.js +1 -0
  10. package/dist/skill-core/adapters/claudecode-adapter.js +35 -0
  11. package/dist/skill-core/adapters/codex-adapter.js +28 -0
  12. package/dist/skill-core/adapters/iflow-adapter.js +39 -0
  13. package/dist/skill-core/adapters/index.js +34 -0
  14. package/dist/skill-core/adapters/shared.js +36 -0
  15. package/dist/skill-core/agent-config.js +40 -0
  16. package/dist/skill-core/manifest-loader.js +63 -0
  17. package/dist/skill-core/scaffold.js +169 -0
  18. package/dist/skill-core/service.js +156 -0
  19. package/dist/skill-core/tool-interactions.js +70 -0
  20. package/dist/skill-core/types.js +1 -0
  21. package/dist/skill-core/validator.js +25 -0
  22. package/dist/task-core/parser.js +70 -0
  23. package/dist/task-core/service.js +28 -0
  24. package/dist/task-core/storage.js +159 -0
  25. package/dist/task-core/types.js +1 -0
  26. package/dist/utils/frontmatter.js +40 -0
  27. package/dist/utils/fs.js +37 -0
  28. package/package.json +29 -0
  29. package/src/cli.ts +105 -0
  30. package/src/config/default.ts +51 -0
  31. package/src/config/loader.ts +37 -0
  32. package/src/config/path.ts +13 -0
  33. package/src/config/types.ts +22 -0
  34. package/src/skill-core/adapters/claudecode-adapter.ts +45 -0
  35. package/src/skill-core/adapters/codex-adapter.ts +36 -0
  36. package/src/skill-core/adapters/iflow-adapter.ts +49 -0
  37. package/src/skill-core/adapters/index.ts +39 -0
  38. package/src/skill-core/adapters/shared.ts +45 -0
  39. package/src/skill-core/manifest-loader.ts +79 -0
  40. package/src/skill-core/scaffold.ts +192 -0
  41. package/src/skill-core/service.ts +199 -0
  42. package/src/skill-core/tool-interactions.ts +95 -0
  43. package/src/skill-core/types.ts +22 -0
  44. package/src/skill-core/validator.ts +28 -0
  45. package/src/task-core/parser.ts +89 -0
  46. package/src/task-core/service.ts +49 -0
  47. package/src/task-core/storage.ts +177 -0
  48. package/src/task-core/types.ts +15 -0
  49. package/src/types/yaml.d.ts +4 -0
  50. package/src/utils/frontmatter.ts +55 -0
  51. package/src/utils/fs.ts +41 -0
  52. package/templates/design-doc/SKILL.md +99 -0
  53. package/templates/design-doc/agents/openai.yaml +4 -0
  54. package/templates/design-doc/references//345/237/272/347/272/277/346/250/241/346/235/277.md +46 -0
  55. package/templates/design-doc/references//345/242/236/351/207/217/351/234/200/346/261/202/346/250/241/346/235/277.md +32 -0
  56. package/templates/design-doc/references//345/275/222/346/241/243/346/243/200/346/237/245/346/270/205/345/215/225.md +15 -0
  57. package/templates/design-doc/references//347/224/237/344/272/247/345/267/245/345/215/225/345/237/272/347/272/277/347/244/272/344/276/213.md +470 -0
  58. package/templates/design-doc/scripts/validate_doc_layout.sh +49 -0
  59. package/templates/frontend-develop-standard/SKILL.md +63 -0
  60. package/templates/frontend-develop-standard/agents/openai.yaml +4 -0
  61. package/templates/frontend-develop-standard/references/frontend_develop_standard.md +749 -0
  62. package/templates/standards-backend/SKILL.md +55 -0
  63. package/templates/standards-backend/agents/openai.yaml +4 -0
  64. package/templates/standards-backend/references/DDD/346/236/266/346/236/204/347/272/246/346/235/237.md +103 -0
  65. package/templates/standards-backend/references/JUC/345/271/266/345/217/221/350/247/204/350/214/203.md +232 -0
  66. package/templates/standards-backend/references//344/274/240/347/273/237/344/270/211/345/261/202/346/236/266/346/236/204/347/272/246/346/235/237.md +35 -0
  67. package/templates/standards-backend/references//345/220/216/347/253/257/345/274/200/345/217/221/350/247/204/350/214/203.md +49 -0
  68. package/templates/standards-backend/references//346/225/260/346/215/256/345/272/223/350/256/276/350/256/241/350/247/204/350/214/203.md +116 -0
  69. package/templates/standards-backend/references//350/256/276/350/256/241/346/250/241/345/274/217/350/220/275/345/234/260/346/211/213/345/206/214.md +395 -0
  70. package/tests/skill.test.ts +191 -0
  71. package/tests/task.test.ts +55 -0
  72. package/tsconfig.json +16 -0
  73. package/vitest.config.ts +9 -0
@@ -0,0 +1,749 @@
1
+ # 前端开发规范
2
+
3
+ ## 一、Vue3 编码规范
4
+
5
+ ### 1.1 命名规范
6
+
7
+ #### 1.1.1 组件命名
8
+
9
+ **文件夹和文件名**
10
+ - 使用小驼峰命名法(camelCase)
11
+ - 示例:`testList/testList.vue`
12
+
13
+ **组件引用**
14
+ ```vue
15
+ <template>
16
+ <!-- 自闭合组件 -->
17
+ <test-component />
18
+
19
+ <!-- 包含内容的组件 -->
20
+ <container-component>
21
+ This is content
22
+ </container-component>
23
+ </template>
24
+
25
+ <script setup>
26
+ import TestComponent from './components/TestComponent.vue'
27
+ import ContainerComponent from './components/ContainerComponent.vue'
28
+ </script>
29
+ ```
30
+
31
+ #### 1.1.2 变量和常量命名
32
+
33
+ **变量命名**
34
+ - 使用小驼峰命名法(camelCase)
35
+ - 语义化,见名知意
36
+
37
+ ```javascript
38
+ // 推荐
39
+ let userInfo = {}
40
+ let infoList = []
41
+ let isLoading = false
42
+
43
+ // 不推荐
44
+ let a = {}
45
+ let data = []
46
+ ```
47
+
48
+ **常量命名**
49
+ - 使用全大写字母,单词间用下划线分隔
50
+ - 语义化,见名知意
51
+
52
+ ```javascript
53
+ // 推荐
54
+ const MAX_NUMBER = 10
55
+ const API_BASE_URL = 'https://api.example.com'
56
+ const DEFAULT_PAGE_SIZE = 20
57
+
58
+ // 不推荐
59
+ const max = 10
60
+ const url = 'https://api.example.com'
61
+ ```
62
+
63
+ #### 1.1.3 接口类型命名
64
+
65
+ 接口类型以大写字母 `C` 为前缀:
66
+
67
+ ```typescript
68
+ export interface CState {
69
+ roleList: Object
70
+ restartVisible: boolean
71
+ sid: string
72
+ dialogVisible: boolean
73
+ loading: boolean
74
+ list: CDevmemt[]
75
+ total: number
76
+ listQuery: CListQuery
77
+ name: string
78
+ }
79
+
80
+ export interface CStateParams extends CState {
81
+ id: string
82
+ }
83
+ ```
84
+
85
+ ### 1.2 代码风格
86
+
87
+ #### 1.2.1 引号使用规范
88
+
89
+ - HTML 属性使用双引号 `""`
90
+ - JavaScript 代码使用单引号 `''`
91
+
92
+ ```vue
93
+ <template>
94
+ <test-component data-attributes="test" class="container" />
95
+ </template>
96
+
97
+ <script setup>
98
+ const str = 'hello world'
99
+ const message = 'This is a message'
100
+ </script>
101
+ ```
102
+
103
+ #### 1.2.2 多属性换行
104
+
105
+ 当元素有多个属性时,每个属性独占一行:
106
+
107
+ ```vue
108
+ <template>
109
+ <a-table-column
110
+ data-index="name"
111
+ title="名称"
112
+ :width="180"
113
+ align="center"
114
+ :sorter="true"
115
+ />
116
+
117
+ <li
118
+ v-for="(item, index) in testList"
119
+ :key="index"
120
+ :span="4"
121
+ style="margin-bottom: 10px"
122
+ >
123
+ {{ item.name }}
124
+ </li>
125
+ </template>
126
+ ```
127
+
128
+ #### 1.2.3 组件样式作用域
129
+
130
+ 组件样式必须设置作用域,避免样式污染:
131
+
132
+ ```vue
133
+ <style scoped lang="less">
134
+ .test-list {
135
+ padding: 20px;
136
+
137
+ .test-item {
138
+ margin-bottom: 10px;
139
+ }
140
+ }
141
+ </style>
142
+ ```
143
+
144
+ #### 1.2.4 样式穿透
145
+
146
+ 使用 `:deep()` 进行样式穿透:
147
+
148
+ ```vue
149
+ <style scoped lang="less">
150
+ :deep(.ant-card-body) {
151
+ padding: 20px;
152
+ }
153
+
154
+ :deep(.ant-table) {
155
+ .ant-table-thead {
156
+ background-color: #f5f7fa;
157
+ }
158
+ }
159
+ </style>
160
+ ```
161
+
162
+ ### 1.3 组件开发规范
163
+
164
+ #### 1.3.1 生命周期钩子顺序
165
+
166
+ 按照执行顺序排列生命周期钩子:
167
+
168
+ ```vue
169
+ <script setup lang="ts" name="componentName">
170
+ import { onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted } from 'vue'
171
+
172
+ // 1. 挂载前
173
+ onBeforeMount(() => {
174
+ console.log('onBeforeMount')
175
+ })
176
+
177
+ // 2. 挂载后
178
+ onMounted(() => {
179
+ console.log('onMounted')
180
+ })
181
+
182
+ // 3. 更新前
183
+ onBeforeUpdate(() => {
184
+ console.log('onBeforeUpdate')
185
+ })
186
+
187
+ // 4. 更新后
188
+ onUpdated(() => {
189
+ console.log('onUpdated')
190
+ })
191
+
192
+ // 5. 卸载前
193
+ onBeforeUnmount(() => {
194
+ console.log('onBeforeUnmount')
195
+ })
196
+
197
+ // 6. 卸载后
198
+ onUnmounted(() => {
199
+ console.log('onUnmounted')
200
+ })
201
+ </script>
202
+ ```
203
+
204
+ #### 1.3.2 自定义事件命名
205
+
206
+ - 事件名使用 `on-` 前缀 + 动词
207
+ - 事件处理函数使用 `handle` 前缀 + 动词
208
+
209
+ ```vue
210
+ <!-- 父组件 -->
211
+ <template>
212
+ <my-component @on-change="handleChange" @on-submit="handleSubmit" />
213
+ </template>
214
+
215
+ <script setup>
216
+ const handleChange = (value) => {
217
+ console.log('value changed:', value)
218
+ }
219
+
220
+ const handleSubmit = (data) => {
221
+ console.log('form submitted:', data)
222
+ }
223
+ </script>
224
+
225
+ <!-- 子组件 -->
226
+ <script setup>
227
+ const emit = defineEmits(['on-change', 'on-submit'])
228
+
229
+ const onChange = () => {
230
+ emit('on-change', newValue)
231
+ }
232
+
233
+ const onSubmit = () => {
234
+ emit('on-submit', formData)
235
+ }
236
+ </script>
237
+ ```
238
+
239
+ ### 1.4 注释规范
240
+
241
+ #### 1.4.1 模板注释
242
+
243
+ ```vue
244
+ <template>
245
+ <div>
246
+ <!-- 用户信息表单 -->
247
+ <a-form>
248
+ <!-- 用户名 -->
249
+ <a-form-item label="用户名" name="username">
250
+ <a-input v-model:value="form.username" />
251
+ </a-form-item>
252
+
253
+ <!-- 邮箱 -->
254
+ <a-form-item label="邮箱" name="email">
255
+ <a-input v-model:value="form.email" />
256
+ </a-form-item>
257
+ </a-form>
258
+ </div>
259
+ </template>
260
+ ```
261
+
262
+ #### 1.4.2 脚本注释
263
+
264
+ ```javascript
265
+ // 删除用户
266
+ const deleteUser = (id) => {
267
+ // 实现逻辑
268
+ }
269
+
270
+ // 新增用户
271
+ const addUser = (userData) => {
272
+ // 实现逻辑
273
+ }
274
+
275
+ /**
276
+ * 更新用户信息
277
+ * @param {string} id - 用户ID
278
+ * @param {Object} userData - 用户数据
279
+ * @returns {Promise} 返回更新结果
280
+ */
281
+ const updateUser = async (id, userData) => {
282
+ // 实现逻辑
283
+ }
284
+ ```
285
+
286
+ ### 1.5 代码质量
287
+
288
+ #### 1.5.1 移除调试代码
289
+
290
+ 提交代码前必须移除:
291
+ - `console.log()`
292
+ - `debugger`
293
+ - 注释掉的无用代码
294
+
295
+ ```javascript
296
+ // ❌ 不推荐
297
+ const fetchData = () => {
298
+ console.log('fetching data...')
299
+ debugger
300
+ // const oldCode = 'something'
301
+ return api.getData()
302
+ }
303
+
304
+ // ✅ 推荐
305
+ const fetchData = () => {
306
+ return api.getData()
307
+ }
308
+ ```
309
+
310
+ ### 1.6 完整示例
311
+
312
+ ```vue
313
+ <template>
314
+ <div class="user-form">
315
+ <a-card>
316
+ <a-form
317
+ ref="formRef"
318
+ :model="formState"
319
+ :rules="rules"
320
+ :label-col="{ span: 4 }"
321
+ :wrapper-col="{ span: 20 }"
322
+ >
323
+ <!-- 名称 -->
324
+ <a-form-item label="名称" name="name">
325
+ <a-input v-model:value="formState.name" placeholder="请输入名称" />
326
+ </a-form-item>
327
+
328
+ <!-- 标签 -->
329
+ <a-form-item label="标签" name="label">
330
+ <a-button type="link" @click="addLabel">
331
+ +添加一行
332
+ </a-button>
333
+ <span>(最多 20 个标签)</span>
334
+ </a-form-item>
335
+
336
+ <!-- 描述 -->
337
+ <a-form-item label="描述" name="describe">
338
+ <a-textarea
339
+ v-model:value="formState.describe"
340
+ :rows="2"
341
+ placeholder="请输入描述"
342
+ />
343
+ </a-form-item>
344
+
345
+ <!-- 操作按钮 -->
346
+ <a-form-item :wrapper-col="{ offset: 4, span: 20 }">
347
+ <a-button @click="handleCancel">取消</a-button>
348
+ <a-button type="primary" @click="handleSubmit" style="margin-left: 10px">
349
+ 确认
350
+ </a-button>
351
+ </a-form-item>
352
+ </a-form>
353
+ </a-card>
354
+ </div>
355
+ </template>
356
+
357
+ <script setup lang="ts">
358
+ import { reactive, ref } from 'vue'
359
+ import type { FormInstance, Rule } from 'ant-design-vue/es/form'
360
+ import { useRouter, useRoute } from 'vue-router'
361
+ import { activationApi } from '/@/api/devmgmt'
362
+
363
+ const route = useRoute()
364
+ const router = useRouter()
365
+
366
+ const uuid = route.query.uuid
367
+ const type = route.query.type
368
+
369
+ const formRef = ref<FormInstance>()
370
+ const formState = reactive({
371
+ name: '',
372
+ label: [{ label: '' }],
373
+ longitude: '',
374
+ latitude: '',
375
+ address: '',
376
+ describe: ''
377
+ })
378
+
379
+ // 表单验证规则
380
+ const rules: Record<string, Rule[]> = {
381
+ name: [
382
+ { required: true, message: '请输入设备名称', trigger: 'blur' }
383
+ ]
384
+ }
385
+
386
+ // 新增标签
387
+ const addLabel = () => {
388
+ if (formState.label.length < 20) {
389
+ formState.label.push({ label: '' })
390
+ }
391
+ }
392
+
393
+ // 删除标签
394
+ const removeLabel = (item: any) => {
395
+ const index = formState.label.indexOf(item)
396
+ if (index !== -1) {
397
+ formState.label.splice(index, 1)
398
+ }
399
+ }
400
+
401
+ // 取消操作
402
+ const handleCancel = () => {
403
+ router.back()
404
+ }
405
+
406
+ // 提交表单
407
+ const handleSubmit = async () => {
408
+ if (!formRef.value) return
409
+
410
+ try {
411
+ await formRef.value.validate()
412
+ const label = formState.label.map(item => item.label).filter(Boolean)
413
+
414
+ const params = {
415
+ sid: uuid,
416
+ name: formState.name,
417
+ type: type,
418
+ address: formState.address,
419
+ longitude: parseFloat(formState.longitude),
420
+ latitude: parseFloat(formState.latitude),
421
+ detail: formState.describe,
422
+ label: label
423
+ }
424
+
425
+ activationApi(params).then((res: any) => {
426
+ // 处理成功逻辑
427
+ })
428
+ } catch (error) {
429
+ console.log('验证失败:', error)
430
+ }
431
+ }
432
+ </script>
433
+
434
+ <style scoped lang="scss">
435
+ .user-form {
436
+ padding: 20px;
437
+
438
+ .width120 {
439
+ width: 120px;
440
+ }
441
+
442
+ .latitude-text .width300 {
443
+ width: 300px;
444
+ margin: 0 10px 0 22px;
445
+ }
446
+ }
447
+ </style>
448
+ ```
449
+
450
+ ---
451
+
452
+ ## 二、项目配置规范
453
+
454
+ ### 2.1 EditorConfig 配置
455
+
456
+ EditorConfig 帮助团队维护一致的编码风格。
457
+
458
+ 在项目根目录创建 `.editorconfig` 文件:
459
+
460
+ ```ini
461
+ # http://editorconfig.org
462
+
463
+ root = true
464
+
465
+ [*]
466
+ charset = utf-8
467
+ indent_style = space
468
+ indent_size = 2
469
+ end_of_line = lf
470
+ trim_trailing_whitespace = true
471
+ insert_final_newline = true
472
+
473
+ [*.md]
474
+ max_line_length = off
475
+ trim_trailing_whitespace = false
476
+ ```
477
+
478
+ **配置说明:**
479
+ - `charset`: 文件字符集为 UTF-8
480
+ - `indent_style`: 缩进风格(space 或 tab)
481
+ - `indent_size`: 缩进大小为 2 个空格
482
+ - `end_of_line`: 换行符类型(lf、cr 或 crlf)
483
+ - `trim_trailing_whitespace`: 去除行尾空白字符
484
+ - `insert_final_newline`: 文件末尾插入新行
485
+
486
+ **VSCode 插件:** 需安装 `EditorConfig for VS Code`
487
+
488
+ ### 2.2 Prettier 配置
489
+
490
+ Prettier 是强大的代码格式化工具,支持多种前端语言。
491
+
492
+ 在项目根目录创建 `.prettierrc` 文件:
493
+
494
+ ```json
495
+ {
496
+ "useTabs": false,
497
+ "tabWidth": 2,
498
+ "printWidth": 80,
499
+ "singleQuote": true,
500
+ "trailingComma": "none",
501
+ "semi": false
502
+ }
503
+ ```
504
+
505
+ **配置说明:**
506
+
507
+ | 属性 | 说明 |
508
+ |------|------|
509
+ | useTabs | false: 使用空格缩进,true: 使用 tab 缩进 |
510
+ | tabWidth | 缩进空格数,设置为 2 |
511
+ | printWidth | 单行最大字符数,推荐 80 或 100 |
512
+ | singleQuote | true: 使用单引号,false: 使用双引号 |
513
+ | trailingComma | 多行输入尾逗号,设置为 none |
514
+ | semi | false: 不加分号,true: 加分号 |
515
+
516
+ **VSCode 插件:** 需安装 `Prettier - Code formatter`
517
+
518
+ **常见问题:**
519
+
520
+ 1. **保存代码无法格式化**
521
+ - 原因:未设置默认格式化插件
522
+ - 解决:右键 → 格式化文档 → 选择 Prettier
523
+
524
+ 2. **保存无法自动格式化**
525
+ - 原因:未开启保存时格式化
526
+ - 解决:文件 → 设置 → 搜索 "Format On Save" → 勾选
527
+
528
+ **快速格式化所有文件:**
529
+
530
+ 在 `package.json` 添加脚本:
531
+
532
+ ```json
533
+ {
534
+ "scripts": {
535
+ "prettier": "prettier --write ."
536
+ }
537
+ }
538
+ ```
539
+
540
+ 运行命令:
541
+
542
+ ```bash
543
+ npm run prettier
544
+ ```
545
+
546
+ ### 2.3 Prettier 忽略配置
547
+
548
+ 在项目根目录创建 `.prettierignore` 文件:
549
+
550
+ ```
551
+ /dist/*
552
+ .local
553
+ .output.js
554
+ /node_modules/**
555
+ **/*.svg
556
+ **/*.sh
557
+ /public/*
558
+ ```
559
+
560
+ ### 2.4 ESLint 配置
561
+
562
+ Vue 项目创建时会自动配置 ESLint。
563
+
564
+ **VSCode 插件:** 需安装 `ESLint`
565
+
566
+ **解决 ESLint 和 Prettier 冲突:**
567
+
568
+ 安装插件(Vue 创建项目时选择 Prettier 会自动安装):
569
+
570
+ ```bash
571
+ npm install eslint-plugin-prettier eslint-config-prettier -D
572
+ ```
573
+
574
+ 在 `.eslintrc.js` 文件的 `extends` 中添加:
575
+
576
+ ```javascript
577
+ module.exports = {
578
+ extends: [
579
+ // ... 其他配置
580
+ 'plugin:prettier/recommended'
581
+ ]
582
+ }
583
+ ```
584
+
585
+ **注意:** `plugin:` 和 `prettier` 之间没有空格
586
+
587
+ ---
588
+
589
+ ## 三、Git 提交规范
590
+
591
+ ### 3.1 Husky 配置
592
+
593
+ Husky 用于在 Git 操作时触发钩子。
594
+
595
+ **安装 Husky:**
596
+
597
+ ```bash
598
+ npm install husky -D
599
+ ```
600
+
601
+ **配置 prepare 脚本:**
602
+
603
+ ```bash
604
+ npm set-script prepare "husky install"
605
+ npm run prepare
606
+ ```
607
+
608
+ **添加 pre-commit 钩子:**
609
+
610
+ ```bash
611
+ npx husky add .husky/pre-commit "npx eslint ./"
612
+ ```
613
+
614
+ 如果自动生成失败,手动创建 `.husky/pre-commit` 文件:
615
+
616
+ ```bash
617
+ #!/bin/sh
618
+ . "$(dirname "$0")/_/husky.sh"
619
+
620
+ npx eslint ./
621
+ ```
622
+
623
+ ### 3.2 Commitlint 配置
624
+
625
+ **安装 Commitlint:**
626
+
627
+ ```bash
628
+ npm install --save-dev @commitlint/config-conventional @commitlint/cli
629
+ ```
630
+
631
+ **创建配置文件:**
632
+
633
+ ```bash
634
+ echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js
635
+ ```
636
+
637
+ **注意:** 确保文件编码为 UTF-8
638
+
639
+ **添加 commit-msg 钩子:**
640
+
641
+ ```bash
642
+ npx husky add .husky/commit-msg "npx --no -- commitlint --edit ${1}"
643
+ ```
644
+
645
+ 如果自动生成失败,手动创建 `.husky/commit-msg` 文件:
646
+
647
+ ```bash
648
+ #!/bin/sh
649
+ . "$(dirname "$0")/_/husky.sh"
650
+
651
+ npx --no-install commitlint --edit $1
652
+ ```
653
+
654
+ **禁用 Husky(如需要):**
655
+
656
+ 在 `.git/config` 文件中注释掉:
657
+
658
+ ```
659
+ # hooksPath = .husky
660
+ ```
661
+
662
+ ### 3.3 Commit 提交规范
663
+
664
+ **提交类型说明:**
665
+
666
+ | 类型 | 说明 |
667
+ |------|------|
668
+ | feat | 新增功能 |
669
+ | fix | 修复 Bug |
670
+ | docs | 文档更新 |
671
+ | style | 代码格式调整(不影响功能) |
672
+ | refactor | 代码重构 |
673
+ | perf | 性能优化 |
674
+ | test | 测试相关 |
675
+ | chore | 构建过程或辅助工具的变动 |
676
+ | revert | 回滚提交 |
677
+ | build | 影响构建系统或外部依赖 |
678
+ | ci | CI 配置文件和脚本的变动 |
679
+ | types | 类型定义文件更改 |
680
+ | wip | 开发中(work in progress) |
681
+
682
+ **提交格式:**
683
+
684
+ ```bash
685
+ git commit -m "type: description"
686
+ ```
687
+
688
+ **示例:**
689
+
690
+ ```bash
691
+ # 新增功能
692
+ git commit -m "feat: 添加用户登录功能"
693
+
694
+ # 修复 Bug
695
+ git commit -m "fix: 修复用户列表分页问题"
696
+
697
+ # 文档更新
698
+ git commit -m "docs: 更新 API 文档"
699
+
700
+ # 代码重构
701
+ git commit -m "refactor: 重构用户模块代码结构"
702
+
703
+ # 性能优化
704
+ git commit -m "perf: 优化列表渲染性能"
705
+ ```
706
+
707
+ **完整格式(可选):**
708
+
709
+ ```bash
710
+ git commit -m "feat: 添加用户登录功能
711
+
712
+ - 实现用户名密码登录
713
+ - 添加记住密码功能
714
+ - 集成第三方登录"
715
+ ```
716
+
717
+ ---
718
+
719
+ ## 四、最佳实践建议
720
+
721
+ ### 4.1 代码组织
722
+
723
+ - 按功能模块组织代码,而非按文件类型
724
+ - 保持组件单一职责
725
+ - 合理拆分大型组件
726
+ - 复用性高的代码抽取为公共组件或工具函数
727
+
728
+ ### 4.2 性能优化
729
+
730
+ - 合理使用 `v-if` 和 `v-show`
731
+ - 列表渲染使用唯一 `key`
732
+ - 避免在模板中使用复杂表达式
733
+ - 使用 `computed` 缓存计算结果
734
+ - 大型列表使用虚拟滚动
735
+
736
+ ### 4.3 安全规范
737
+
738
+ - 避免使用 `v-html`,防止 XSS 攻击
739
+ - 敏感信息不要硬编码在前端
740
+ - API 请求添加适当的权限验证
741
+ - 用户输入进行验证和过滤
742
+
743
+ ### 4.4 可维护性
744
+
745
+ - 编写清晰的注释
746
+ - 保持代码简洁易读
747
+ - 遵循团队统一的编码规范
748
+ - 定期进行代码审查
749
+ - 及时更新文档