m8-mcp-server 1.0.5 → 1.0.7

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 (151) hide show
  1. package/dist/cli.d.ts +2 -2
  2. package/dist/cli.js +1 -13
  3. package/dist/docs/apis.d.ts +2 -2
  4. package/dist/docs/apis.js +9 -326
  5. package/dist/docs/components.d.ts +2 -2
  6. package/dist/docs/components.js +2 -186
  7. package/dist/docs/index.d.ts +2 -2
  8. package/dist/docs/index.js +18 -177
  9. package/dist/docs/loader.d.ts +2 -2
  10. package/dist/docs/loader.js +1 -165
  11. package/dist/docs/search.d.ts +2 -2
  12. package/dist/docs/search.js +2 -196
  13. package/dist/docs/standards.d.ts +2 -2
  14. package/dist/docs/standards.js +3 -134
  15. package/dist/docs/utils.d.ts +2 -2
  16. package/dist/docs/utils.js +3 -129
  17. package/dist/generator/header.d.ts +2 -2
  18. package/dist/generator/header.js +3 -83
  19. package/dist/generator/index.d.ts +2 -2
  20. package/dist/generator/index.js +283 -648
  21. package/dist/generator/vue-template.d.ts +2 -2
  22. package/dist/generator/vue-template.js +336 -1016
  23. package/dist/index.d.ts +2 -2
  24. package/dist/index.js +1 -73
  25. package/dist/recommend/index.d.ts +2 -2
  26. package/dist/recommend/index.js +2 -412
  27. package/dist/tools/generate-code.d.ts +2 -2
  28. package/dist/tools/generate-code.js +39 -211
  29. package/dist/tools/get-api-info.d.ts +2 -2
  30. package/dist/tools/get-api-info.js +1 -65
  31. package/dist/tools/get-coding-standard.d.ts +2 -2
  32. package/dist/tools/get-coding-standard.js +1 -66
  33. package/dist/tools/get-component-info.d.ts +2 -2
  34. package/dist/tools/get-component-info.js +1 -60
  35. package/dist/tools/get-util-info.d.ts +2 -2
  36. package/dist/tools/get-util-info.js +1 -65
  37. package/dist/tools/index.d.ts +2 -2
  38. package/dist/tools/index.js +3 -101
  39. package/dist/tools/recommend-solution.d.ts +2 -2
  40. package/dist/tools/recommend-solution.js +1 -67
  41. package/dist/tools/search-docs.d.ts +2 -2
  42. package/dist/tools/search-docs.js +1 -71
  43. package/dist/types/index.d.ts +2 -2
  44. package/dist/types/index.js +0 -8
  45. package/package.json +6 -5
  46. package/dist/cli.js.map +0 -1
  47. package/dist/docs/apis.js.map +0 -1
  48. package/dist/docs/components.js.map +0 -1
  49. package/dist/docs/index.js.map +0 -1
  50. package/dist/docs/loader.js.map +0 -1
  51. package/dist/docs/search.js.map +0 -1
  52. package/dist/docs/standards.js.map +0 -1
  53. package/dist/docs/utils.js.map +0 -1
  54. package/dist/generator/header.js.map +0 -1
  55. package/dist/generator/index.js.map +0 -1
  56. package/dist/generator/vue-template.js.map +0 -1
  57. package/dist/index.js.map +0 -1
  58. package/dist/recommend/index.js.map +0 -1
  59. package/dist/tools/generate-code.js.map +0 -1
  60. package/dist/tools/get-api-info.js.map +0 -1
  61. package/dist/tools/get-coding-standard.js.map +0 -1
  62. package/dist/tools/get-component-info.js.map +0 -1
  63. package/dist/tools/get-util-info.js.map +0 -1
  64. package/dist/tools/index.js.map +0 -1
  65. package/dist/tools/recommend-solution.js.map +0 -1
  66. package/dist/tools/search-docs.js.map +0 -1
  67. package/dist/types/index.js.map +0 -1
  68. package/resources/cases/.gitkeep +0 -0
  69. package/resources/cases/form-submit-vue2.json +0 -15
  70. package/resources/cases/index.json +0 -8
  71. package/resources/cases/list-detail-vue2.json +0 -27
  72. package/resources/components/.gitkeep +0 -0
  73. package/resources/components/actionsheet.json +0 -199
  74. package/resources/components/amap.json +0 -66
  75. package/resources/components/area.json +0 -158
  76. package/resources/components/badge.json +0 -93
  77. package/resources/components/button.json +0 -260
  78. package/resources/components/calendar.json +0 -225
  79. package/resources/components/cascader.json +0 -115
  80. package/resources/components/cell.json +0 -85
  81. package/resources/components/chart.json +0 -55
  82. package/resources/components/checkbox.json +0 -158
  83. package/resources/components/circle.json +0 -138
  84. package/resources/components/collapse.json +0 -88
  85. package/resources/components/countdown.json +0 -105
  86. package/resources/components/datepicker.json +0 -216
  87. package/resources/components/dialog.json +0 -250
  88. package/resources/components/divider.json +0 -82
  89. package/resources/components/dragsort.json +0 -67
  90. package/resources/components/dropdownmenu.json +0 -129
  91. package/resources/components/easycalendar.json +0 -84
  92. package/resources/components/empty.json +0 -90
  93. package/resources/components/field.json +0 -423
  94. package/resources/components/form.json +0 -156
  95. package/resources/components/grid.json +0 -131
  96. package/resources/components/header.json +0 -147
  97. package/resources/components/icon.json +0 -104
  98. package/resources/components/image.json +0 -169
  99. package/resources/components/imagepreview.json +0 -150
  100. package/resources/components/imagescale.json +0 -245
  101. package/resources/components/index.json +0 -72
  102. package/resources/components/indexbar.json +0 -83
  103. package/resources/components/layout.json +0 -74
  104. package/resources/components/lazyload.json +0 -46
  105. package/resources/components/loading.json +0 -103
  106. package/resources/components/minirefresh.json +0 -341
  107. package/resources/components/noticebar.json +0 -148
  108. package/resources/components/notify.json +0 -60
  109. package/resources/components/numberkeyboard.json +0 -216
  110. package/resources/components/overlay.json +0 -78
  111. package/resources/components/pagination.json +0 -137
  112. package/resources/components/panel.json +0 -87
  113. package/resources/components/passwordinput.json +0 -103
  114. package/resources/components/picker.json +0 -195
  115. package/resources/components/popover.json +0 -161
  116. package/resources/components/popup.json +0 -229
  117. package/resources/components/progress.json +0 -111
  118. package/resources/components/qrcode.json +0 -128
  119. package/resources/components/radio.json +0 -139
  120. package/resources/components/rate.json +0 -157
  121. package/resources/components/rtc.json +0 -35
  122. package/resources/components/search.json +0 -234
  123. package/resources/components/selectperson.json +0 -175
  124. package/resources/components/sidebar.json +0 -74
  125. package/resources/components/skeleton.json +0 -110
  126. package/resources/components/slider.json +0 -159
  127. package/resources/components/stepper.json +0 -241
  128. package/resources/components/steps.json +0 -108
  129. package/resources/components/sticky.json +0 -72
  130. package/resources/components/swipe.json +0 -146
  131. package/resources/components/swipecell.json +0 -118
  132. package/resources/components/switch.json +0 -123
  133. package/resources/components/switchcell.json +0 -123
  134. package/resources/components/tab.json +0 -257
  135. package/resources/components/tabbar.json +0 -137
  136. package/resources/components/table.json +0 -149
  137. package/resources/components/tag.json +0 -149
  138. package/resources/components/toast.json +0 -70
  139. package/resources/components/treeselect.json +0 -106
  140. package/resources/components/uploader.json +0 -283
  141. package/resources/components/verifycode.json +0 -94
  142. package/resources/standards/.gitkeep +0 -0
  143. package/resources/standards/css.json +0 -108
  144. package/resources/standards/javascript.json +0 -129
  145. package/resources/standards/project-structure.json +0 -101
  146. package/resources/standards/vue.json +0 -122
  147. package/resources/utils/.gitkeep +0 -0
  148. package/resources/utils/ajax.json +0 -76
  149. package/resources/utils/common.json +0 -129
  150. package/resources/utils/index.json +0 -7
  151. package/resources/utils/string.json +0 -112
@@ -1,94 +0,0 @@
1
- {
2
- "id": "verifycode",
3
- "name": "em-verifycode",
4
- "title": "验证码",
5
- "description": "验证码组件。",
6
- "props": [
7
- {
8
- "name": "len",
9
- "type": "number",
10
- "default": "4",
11
- "required": false,
12
- "description": "验证码字符串长度"
13
- },
14
- {
15
- "name": "minfontsize",
16
- "type": "number",
17
- "default": "20",
18
- "required": false,
19
- "description": "验证码字符最小字体大小"
20
- },
21
- {
22
- "name": "maxfontsize",
23
- "type": "number",
24
- "default": "35",
25
- "required": false,
26
- "description": "验证码字符最大字体大小"
27
- },
28
- {
29
- "name": "bgColor",
30
- "type": "string",
31
- "default": "#444",
32
- "required": false,
33
- "description": "验证码边框颜色"
34
- },
35
- {
36
- "name": "colors",
37
- "type": "array",
38
- "default": "-",
39
- "required": false,
40
- "description": "自定义验证码每个字符颜色"
41
- },
42
- {
43
- "name": "width",
44
- "type": "number",
45
- "default": "130",
46
- "required": false,
47
- "description": "验证码画布宽度"
48
- },
49
- {
50
- "name": "height",
51
- "type": "number",
52
- "default": "60",
53
- "required": false,
54
- "description": "验证码画布高度"
55
- },
56
- {
57
- "name": "enableCaseValidation",
58
- "type": "boolean",
59
- "default": "false",
60
- "required": false,
61
- "description": "是否开启大小写校验"
62
- },
63
- {
64
- "name": "lines",
65
- "type": "number",
66
- "default": "8",
67
- "required": false,
68
- "description": "干扰线数量"
69
- },
70
- {
71
- "name": "points",
72
- "type": "number",
73
- "default": "100",
74
- "required": false,
75
- "description": "干扰点数量"
76
- }
77
- ],
78
- "events": [],
79
- "slots": [],
80
- "examples": {
81
- "vue2": [
82
- {
83
- "title": "基础用法",
84
- "code": "<em-field placeholder=\"请输入验证码\" v-model=\"value\"></em-field>\n<em-verify-code :width=\"160\" style=\"margin: 10px;\" ref=\"verifycode\"></em-verify-code>\n<em-button class=\"mr10\" type=\"primary\" plain @click=\"checkVerifyCode\">校验验证码</em-button>\n<em-button type=\"danger\" plain @click=\"updateVerify\">更新验证码</em-button>"
85
- }
86
- ],
87
- "vue3": [
88
- {
89
- "title": "基础用法",
90
- "code": "<em-field placeholder=\"请输入验证码\" v-model=\"value\"></em-field>\n<em-verify-code :width=\"160\" style=\"margin: 10px;\" ref=\"verifycode\"></em-verify-code>\n<em-button class=\"mr10\" type=\"primary\" plain @click=\"checkVerifyCode\">校验验证码</em-button>\n<em-button type=\"danger\" plain @click=\"updateVerify\">更新验证码</em-button>"
91
- }
92
- ]
93
- }
94
- }
File without changes
@@ -1,108 +0,0 @@
1
- {
2
- "id": "css-style",
3
- "category": "css",
4
- "title": "CSS/SCSS 编码规范",
5
- "version": "1.1.0",
6
- "lastUpdated": "2024-12-19",
7
- "description": "M8 框架项目中 CSS/SCSS 的编码标准",
8
- "rules": [
9
- {
10
- "id": "css-variables",
11
- "title": "使用 SASS 变量统一管理颜色和样式",
12
- "description": "整体风格(颜色、字体、间距等)必须使用 SASS 变量统一管理,禁止在代码中硬编码颜色值。",
13
- "correctExample": "// 在 variables.scss 中定义\n$color-primary: #1890ff;\n$color-text-primary: #333;\n\n// 使用变量\n.button {\n background-color: $color-primary;\n color: $color-text-primary;\n}",
14
- "incorrectExample": ".button {\n background-color: #1890ff;\n color: #333333;\n}"
15
- },
16
- {
17
- "id": "css-bem",
18
- "title": "BEM 命名规范",
19
- "description": "推荐使用 BEM (Block Element Modifier) 命名规范。块: block,元素: block__element,修饰符: block--modifier",
20
- "correctExample": ".card { }\n.card__header { }\n.card__header--active { }",
21
- "incorrectExample": ".card-header-active { }"
22
- },
23
- {
24
- "id": "css-naming",
25
- "title": "类名使用小写英文、数字和下划线组合",
26
- "description": "样式名称由小写英文、数字和下划线组合命名,避免使用中文拼音,命名要语义化、简明化。",
27
- "correctExample": ".page_header { }\n.nav_item { }\n.btn_primary { }\n.user_avatar { }",
28
- "incorrectExample": ".yonghu_touxiang { } // 中文拼音\n.pageHeader { } // 驼峰命名\n.a1 { } // 不语义化"
29
- },
30
- {
31
- "id": "css-deep-selectors",
32
- "title": "样式穿透 (Deep Selectors)",
33
- "description": "Vue2 使用 ::v-deep,Vue3 使用 :deep()。使用样式穿透后,禁止结合 BEM 后缀选择器。",
34
- "correctExample": ":deep(.em-cell) {\n // .em-cell 的样式\n}\n\n:deep(.em-cell__title) {\n // .em-cell__title 的样式\n}",
35
- "incorrectExample": ":deep(.em-cell) {\n &__title { } // Sass 无法正确编译\n}"
36
- },
37
- {
38
- "id": "css-no-id",
39
- "title": "避免使用 ID 选择器",
40
- "description": "ID 选择器优先级过高,不利于样式复用和覆盖。",
41
- "correctExample": ".header { }\n.main_content { }",
42
- "incorrectExample": "#header { }\n#main_content { }"
43
- },
44
- {
45
- "id": "css-no-tag",
46
- "title": "尽量少使用标签选择器",
47
- "description": "避免直接使用标签选择器,使用类选择器代替。",
48
- "correctExample": ".nav_link { }\n.list_item { }",
49
- "incorrectExample": "a { }\nli { }\ndiv { }"
50
- },
51
- {
52
- "id": "css-selector-newline",
53
- "title": "多选择器情况,每个选择器单独占一行",
54
- "description": "当有多个选择器时,每个选择器应该单独占一行。",
55
- "correctExample": ".header,\n.footer,\n.sidebar {\n padding: 16px;\n}",
56
- "incorrectExample": ".header, .footer, .sidebar { padding: 16px; }"
57
- },
58
- {
59
- "id": "css-nesting-depth",
60
- "title": "选择器嵌套不超过 3 层",
61
- "description": "过深的嵌套会增加选择器优先级,降低性能。",
62
- "correctExample": ".card {\n .card_header {\n .card_title { }\n }\n}",
63
- "incorrectExample": ".page {\n .content {\n .card {\n .card_header {\n .card_title { }\n }\n }\n }\n}"
64
- },
65
- {
66
- "id": "css-property-order",
67
- "title": "CSS 推荐书写顺序",
68
- "description": "按以下顺序排列 CSS 属性:1.位置属性 2.大小 3.文字系列 4.背景 5.其他",
69
- "correctExample": ".element {\n /* 1. 位置属性 */\n position: absolute;\n display: flex;\n /* 2. 大小 */\n width: 100%;\n padding: 16px;\n /* 3. 文字系列 */\n font-size: 14px;\n color: #333;\n /* 4. 背景 */\n background: #fff;\n border: 1px solid #eee;\n /* 5. 其他 */\n transition: all 0.3s;\n}",
70
- "incorrectExample": ".element {\n color: #333;\n position: absolute;\n background: #fff;\n width: 100%;\n}"
71
- },
72
- {
73
- "id": "css-position-zindex",
74
- "title": "使用 position 定位时,必须加上 z-index",
75
- "description": "当使用 position: fixed/absolute 时,必须指定 z-index 值。",
76
- "correctExample": ".modal {\n position: fixed;\n top: 0;\n left: 0;\n z-index: 1000;\n}",
77
- "incorrectExample": ".modal {\n position: fixed;\n top: 0;\n left: 0;\n}"
78
- },
79
- {
80
- "id": "css-hex-shorthand",
81
- "title": "16 进制颜色值可缩写时必须缩写",
82
- "description": "当设置的颜色是 16 进制的色彩值时,如果每两位的值相同,必须缩写。",
83
- "correctExample": ".text {\n color: #333;\n background: #fff;\n}",
84
- "incorrectExample": ".text {\n color: #333333;\n background: #ffffff;\n}"
85
- },
86
- {
87
- "id": "css-zero-unit",
88
- "title": "避免为 0 值指定单位",
89
- "description": "当值为 0 时,不需要指定单位。",
90
- "correctExample": ".element {\n margin: 0;\n padding: 0;\n}",
91
- "incorrectExample": ".element {\n margin: 0px;\n padding: 0px;\n}"
92
- },
93
- {
94
- "id": "css-no-important",
95
- "title": "避免使用 !important",
96
- "description": "!important 会破坏样式的层叠规则,应该通过提高选择器优先级来解决。",
97
- "correctExample": ".page .button {\n color: red;\n}",
98
- "incorrectExample": ".button {\n color: red !important;\n}"
99
- },
100
- {
101
- "id": "css-no-inline",
102
- "title": "避免使用内联样式",
103
- "description": "内联样式难以维护和复用,应该使用类选择器。",
104
- "correctExample": "<div class=\"highlight_text\">内容</div>",
105
- "incorrectExample": "<div style=\"color: red; font-size: 14px;\">内容</div>"
106
- }
107
- ]
108
- }
@@ -1,129 +0,0 @@
1
- {
2
- "id": "js-style",
3
- "category": "javascript",
4
- "title": "JavaScript/TypeScript 编码规范",
5
- "version": "1.0.0",
6
- "lastUpdated": "2024-12-19",
7
- "description": "M8 框架项目中 JavaScript/TypeScript 的编码标准",
8
- "rules": [
9
- {
10
- "id": "js-camelcase",
11
- "title": "变量和函数使用 camelCase",
12
- "description": "变量名和函数名应该使用小驼峰命名法。",
13
- "correctExample": "const userName = 'John';\nconst itemCount = 10;\nfunction getUserInfo() { }\nfunction handleClick() { }",
14
- "incorrectExample": "const user_name = 'John';\nconst ItemCount = 10;\nfunction GetUserInfo() { }"
15
- },
16
- {
17
- "id": "js-constants",
18
- "title": "常量使用 UPPER_SNAKE_CASE",
19
- "description": "常量应该使用全大写加下划线的命名方式。",
20
- "correctExample": "const MAX_COUNT = 100;\nconst API_BASE_URL = '/api';\nconst DEFAULT_PAGE_SIZE = 20;",
21
- "incorrectExample": "const maxCount = 100;\nconst apiBaseUrl = '/api';"
22
- },
23
- {
24
- "id": "js-class-pascalcase",
25
- "title": "类和组件使用 PascalCase",
26
- "description": "类名和组件名应该使用大驼峰命名法。",
27
- "correctExample": "class UserService { }\nclass DataManager { }\nconst UserProfile = defineComponent({ });",
28
- "incorrectExample": "class userService { }\nclass data_manager { }"
29
- },
30
- {
31
- "id": "js-single-responsibility",
32
- "title": "函数应该只做一件事",
33
- "description": "每个函数应该只负责一个功能,保持函数的单一职责。",
34
- "correctExample": "function validateEmail(email) {\n return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email);\n}\n\nfunction formatUserName(user) {\n return `${user.firstName} ${user.lastName}`;\n}",
35
- "incorrectExample": "function processUser(user) {\n // 验证、格式化、保存、发送通知都在一个函数里\n}"
36
- },
37
- {
38
- "id": "js-default-params",
39
- "title": "使用默认参数",
40
- "description": "使用 ES6 默认参数语法代替手动检查和赋值。",
41
- "correctExample": "function createUser(name, role = 'user', active = true) {\n return { name, role, active };\n}",
42
- "incorrectExample": "function createUser(name, role, active) {\n role = role || 'user';\n active = active !== undefined ? active : true;\n}"
43
- },
44
- {
45
- "id": "js-destructuring",
46
- "title": "使用解构参数",
47
- "description": "当函数参数较多时,使用对象解构使代码更清晰。",
48
- "correctExample": "function updateUser({ id, name, email }) {\n // ...\n}\n\nupdateUser({ id: 1, name: 'John', email: 'john@example.com' });",
49
- "incorrectExample": "function updateUser(id, name, email) {\n // ...\n}"
50
- },
51
- {
52
- "id": "js-async-await",
53
- "title": "优先使用 async/await",
54
- "description": "异步操作优先使用 async/await 语法,避免回调地狱。",
55
- "correctExample": "async function fetchUserData(userId) {\n try {\n const response = await Util.ajax({\n url: `${Config.serverUrl}/api/user/${userId}`,\n type: 'GET'\n });\n return response.data;\n } catch (error) {\n console.error('获取用户数据失败:', error);\n throw error;\n }\n}",
56
- "incorrectExample": "function fetchUserData(userId, callback) {\n Util.ajax({\n url: url,\n success: (response) => {\n Util.ajax({\n // 嵌套回调...\n });\n }\n });\n}"
57
- },
58
- {
59
- "id": "js-promise-all",
60
- "title": "并发请求使用 Promise.all",
61
- "description": "多个独立的异步请求应该使用 Promise.all 并发执行。",
62
- "correctExample": "async function loadPageData() {\n const [users, products, orders] = await Promise.all([\n fetchUsers(),\n fetchProducts(),\n fetchOrders()\n ]);\n return { users, products, orders };\n}",
63
- "incorrectExample": "async function loadPageData() {\n const users = await fetchUsers();\n const products = await fetchProducts();\n const orders = await fetchOrders();\n}"
64
- },
65
- {
66
- "id": "js-try-catch",
67
- "title": "使用 try-catch 处理异步错误",
68
- "description": "异步操作必须使用 try-catch 进行错误处理。",
69
- "correctExample": "async function submitForm(data) {\n try {\n const result = await Util.ajax({\n url: Config.serverUrl + '/api/submit',\n type: 'POST',\n data: { params: JSON.stringify(data) }\n });\n return result.data;\n } catch (error) {\n console.error('表单提交失败:', error);\n ejs.ui.toast({ message: error.message || '网络错误,请重试' });\n throw error;\n }\n}",
70
- "incorrectExample": "async function submitForm(data) {\n const result = await Util.ajax({ ... });\n return result.data;\n}"
71
- },
72
- {
73
- "id": "js-meaningful-errors",
74
- "title": "提供有意义的错误信息",
75
- "description": "抛出的错误应该包含有意义的描述信息。",
76
- "correctExample": "function validateAge(age) {\n if (typeof age !== 'number') {\n throw new TypeError(`年龄必须是数字,收到: ${typeof age}`);\n }\n if (age < 0 || age > 150) {\n throw new RangeError(`年龄必须在 0-150 之间,收到: ${age}`);\n }\n}",
77
- "incorrectExample": "function validateAge(age) {\n if (typeof age !== 'number' || age < 0 || age > 150) {\n throw new Error('Invalid');\n }\n}"
78
- },
79
- {
80
- "id": "js-util-ajax",
81
- "title": "使用 Util.ajax 进行 HTTP 请求",
82
- "description": "M8 框架中必须使用 Util.ajax 进行网络请求,禁止使用 fetch 或 axios。",
83
- "correctExample": "const result = await Util.ajax({\n url: Config.serverUrl + '/api/data',\n type: 'POST',\n data: { params: JSON.stringify(params) },\n dataPath: 'data'\n});",
84
- "incorrectExample": "const result = await fetch('/api/data');\nconst result = await axios.get('/api/data');"
85
- },
86
- {
87
- "id": "js-config-url",
88
- "title": "使用 Config 管理配置",
89
- "description": "API 地址等配置必须使用 Config 对象,禁止硬编码。",
90
- "correctExample": "const apiUrl = Config.serverUrl + '/api/users';",
91
- "incorrectExample": "const apiUrl = 'http://localhost:3000/api/users';"
92
- },
93
- {
94
- "id": "js-no-var",
95
- "title": "避免使用 var",
96
- "description": "使用 const 和 let 代替 var。",
97
- "correctExample": "const name = 'John'; // 不会重新赋值\nlet count = 0; // 会重新赋值",
98
- "incorrectExample": "var count = 0;\nvar name = 'John';"
99
- },
100
- {
101
- "id": "js-no-mutate-params",
102
- "title": "避免修改函数参数",
103
- "description": "不要直接修改函数参数,应该返回新对象。",
104
- "correctExample": "function updateUser(user) {\n return {\n ...user,\n name: 'New Name'\n };\n}",
105
- "incorrectExample": "function updateUser(user) {\n user.name = 'New Name';\n return user;\n}"
106
- },
107
- {
108
- "id": "js-strict-equality",
109
- "title": "避免使用 == 进行比较",
110
- "description": "使用严格相等 === 代替宽松相等 ==。",
111
- "correctExample": "if (count === 0) { }",
112
- "incorrectExample": "if (value == null) { }\nif (count == '0') { }"
113
- },
114
- {
115
- "id": "js-util-string",
116
- "title": "使用 Util.string 进行字符串校验",
117
- "description": "优先使用 Util.string 提供的校验方法,而不是手写正则。",
118
- "correctExample": "Util.string.isMobile('13800000000');\nUtil.string.isEmail('test@example.com');\nUtil.string.isIdCard('110101199001011234');",
119
- "incorrectExample": "/^1[3-9]\\d{9}$/.test('13800000000');"
120
- },
121
- {
122
- "id": "js-console-log",
123
- "title": "日志输出规范",
124
- "description": "禁止使用无参数的 console.log,必须包含日志信息描述。",
125
- "correctExample": "console.log('提交表单数据:', data);\nconsole.error('接口请求失败:', err);",
126
- "incorrectExample": "console.log(data);"
127
- }
128
- ]
129
- }
@@ -1,101 +0,0 @@
1
- {
2
- "id": "project-structure",
3
- "category": "project-structure",
4
- "title": "项目结构规范",
5
- "version": "1.0.0",
6
- "lastUpdated": "2024-12-19",
7
- "description": "M8 框架项目的目录结构和文件组织标准",
8
- "rules": [
9
- {
10
- "id": "project-standard-structure",
11
- "title": "标准项目结构",
12
- "description": "M8 项目应该遵循标准的目录结构,包括 src/api、src/assets、src/components、src/pages、src/router、src/store、src/utils 等目录。",
13
- "correctExample": "project/\n├── src/\n│ ├── api/ # API 接口定义\n│ ├── assets/ # 静态资源\n│ ├── components/ # 公共组件\n│ ├── pages/ # 页面组件\n│ ├── router/ # 路由配置\n│ ├── store/ # 状态管理\n│ ├── utils/ # 工具函数\n│ ├── App.vue\n│ └── main.js",
14
- "incorrectExample": "project/\n├── src/\n│ ├── all-files-in-one-folder/"
15
- },
16
- {
17
- "id": "project-component-naming",
18
- "title": "组件文件命名使用 PascalCase",
19
- "description": "组件文件使用 PascalCase 命名。",
20
- "correctExample": "components/\n├── UserProfile.vue\n├── TodoList.vue\n└── common/\n ├── BaseButton.vue\n └── BaseInput.vue",
21
- "incorrectExample": "components/\n├── userProfile.vue\n├── todo-list.vue"
22
- },
23
- {
24
- "id": "project-page-structure",
25
- "title": "页面文件按模块划分",
26
- "description": "页面文件应严格按照模块划分,每个模块对应一个文件夹。",
27
- "correctExample": "pages/\n├── home/\n│ └── index.vue\n├── user/\n│ ├── index.vue\n│ ├── profile.vue\n│ └── settings.vue\n└── order/\n ├── list.vue\n └── detail.vue",
28
- "incorrectExample": "pages/\n├── home.vue\n├── user.vue\n├── user-profile.vue"
29
- },
30
- {
31
- "id": "project-utils-naming",
32
- "title": "工具函数文件使用 kebab-case",
33
- "description": "工具函数文件使用 kebab-case 命名。",
34
- "correctExample": "utils/\n├── date-format.js\n├── string-utils.js\n├── validate.js\n└── index.js",
35
- "incorrectExample": "utils/\n├── dateFormat.js\n├── StringUtils.js"
36
- },
37
- {
38
- "id": "project-api-organization",
39
- "title": "按模块组织 API",
40
- "description": "API 接口应该按模块组织,并在 index.js 中统一导出。",
41
- "correctExample": "// api/user.js\nexport function getUserInfo(userId) {\n return request({\n url: `/api/user/${userId}`,\n method: 'GET'\n });\n}\n\n// api/index.js\nexport * from './user';\nexport * from './order';",
42
- "incorrectExample": "// 所有 API 都写在一个文件里"
43
- },
44
- {
45
- "id": "project-request-wrapper",
46
- "title": "请求封装",
47
- "description": "应该封装统一的请求方法,使用 Util.ajax 和 Config.serverUrl。",
48
- "correctExample": "// api/request.js\nexport function request(options) {\n return Util.ajax({\n url: Config.serverUrl + options.url,\n type: options.method || 'POST',\n data: options.data ? { params: JSON.stringify(options.data) } : undefined\n });\n}",
49
- "incorrectExample": "// 每个 API 都直接调用 fetch 或 axios"
50
- },
51
- {
52
- "id": "project-common-components",
53
- "title": "公共组件使用 Base 或 Ne 前缀",
54
- "description": "公共组件放在 components/common/ 目录下,使用 Base 或 Ne 前缀。",
55
- "correctExample": "components/\n├── common/\n│ ├── BaseButton.vue\n│ ├── BaseInput.vue\n│ └── index.js\n└── business/\n ├── UserCard.vue\n └── OrderItem.vue",
56
- "incorrectExample": "components/\n├── Button.vue\n├── Input.vue"
57
- },
58
- {
59
- "id": "project-page-components",
60
- "title": "页面级组件放在页面目录下",
61
- "description": "页面特有的组件放在页面目录下的 components/ 子目录中。",
62
- "correctExample": "pages/\n└── order/\n ├── index.vue\n ├── detail.vue\n └── components/\n ├── OrderHeader.vue\n └── OrderItems.vue",
63
- "incorrectExample": "// 页面特有组件放在全局 components 目录"
64
- },
65
- {
66
- "id": "project-vuex-modules",
67
- "title": "Vuex 模块化 (M8.3)",
68
- "description": "Vuex 状态管理应该按模块划分。",
69
- "correctExample": "store/\n├── index.js\n└── modules/\n ├── user.js\n ├── cart.js\n └── order.js",
70
- "incorrectExample": "store/\n└── index.js // 所有状态都在一个文件里"
71
- },
72
- {
73
- "id": "project-pinia-modules",
74
- "title": "Pinia 模块化 (M8.4)",
75
- "description": "Pinia 状态管理应该按模块划分,使用 useXxxStore 命名。",
76
- "correctExample": "store/\n├── index.js\n└── modules/\n ├── useUserStore.js\n ├── useCartStore.js\n └── useOrderStore.js",
77
- "incorrectExample": "store/\n└── index.js // 所有状态都在一个文件里"
78
- },
79
- {
80
- "id": "project-styles-organization",
81
- "title": "全局样式组织",
82
- "description": "全局样式应该放在 assets/styles/ 目录下统一管理。",
83
- "correctExample": "assets/\n└── styles/\n ├── index.scss\n ├── variables.scss\n ├── mixins.scss\n ├── reset.scss\n └── utils.scss",
84
- "incorrectExample": "// 样式文件散落在各处"
85
- },
86
- {
87
- "id": "project-no-deep-nesting",
88
- "title": "避免过深的目录嵌套",
89
- "description": "目录结构应该保持扁平化,避免过深的嵌套。",
90
- "correctExample": "src/pages/user/profile.vue\nsrc/components/UserAvatar.vue",
91
- "incorrectExample": "src/modules/user/pages/profile/components/header/UserAvatar.vue"
92
- },
93
- {
94
- "id": "project-no-circular-deps",
95
- "title": "避免循环依赖",
96
- "description": "模块之间不应该存在循环依赖,应该提取公共依赖。",
97
- "correctExample": "// constants.js\nexport const BASE = 1;\n\n// a.js\nimport { BASE } from './constants';\nexport const a = BASE + 1;\n\n// b.js\nimport { BASE } from './constants';\nexport const b = BASE + 2;",
98
- "incorrectExample": "// a.js\nimport { b } from './b';\nexport const a = b + 1;\n\n// b.js\nimport { a } from './a';\nexport const b = a + 1;"
99
- }
100
- ]
101
- }
@@ -1,122 +0,0 @@
1
- {
2
- "id": "vue-style",
3
- "category": "vue",
4
- "title": "Vue 组件编码规范",
5
- "version": "1.2.0",
6
- "lastUpdated": "2024-12-22",
7
- "description": "M8 框架 Vue 组件的编码标准,适用于 M8.3 (Vue2) 和 M8.4 (Vue3) 项目",
8
- "rules": [
9
- {
10
- "id": "vue-file-header",
11
- "title": ".vue 文件必须包含头部注释",
12
- "description": "每个 .vue 文件必须在顶部添加标准化的注释块,包含作者、时间、版本、版权和描述信息。",
13
- "correctExample": "<!--\n * @作者: 张三\n * @创建时间: 2024-11-11 14:20:03\n * @修改时间: 2024-11-11 14:20:03\n * @版本: [1.0]\n * @版权: 国泰新点软件股份有限公司\n * @描述: 用户信息展示组件\n-->\n<template>\n <!-- 组件内容 -->\n</template>",
14
- "incorrectExample": "<template>\n <!-- 缺少头部注释 -->\n</template>"
15
- },
16
- {
17
- "id": "vue-component-naming",
18
- "title": "组件文件命名使用 PascalCase",
19
- "description": "组件文件名应使用 PascalCase 命名法。",
20
- "correctExample": "UserProfile.vue\nTodoList.vue\nSearchInput.vue",
21
- "incorrectExample": "userProfile.vue\nuser-profile.vue\ntodolist.vue"
22
- },
23
- {
24
- "id": "vue-base-component-prefix",
25
- "title": "基础组件使用特定前缀",
26
- "description": "应用特定样式和约定的基础组件应该全部以一个特定的前缀开头,比如 Base、App 或 Ne。",
27
- "correctExample": "BaseButton.vue\nBaseTable.vue\nNeInput.vue",
28
- "incorrectExample": "MyButton.vue\nVueTable.vue"
29
- },
30
- {
31
- "id": "vue-props-type",
32
- "title": "Props 必须指定类型",
33
- "description": "Props 定义应该尽量详细,至少需要指定其类型。",
34
- "correctExample": "// Vue2\nexport default {\n props: {\n status: {\n type: String,\n required: true\n },\n count: {\n type: Number,\n default: 0\n }\n }\n}\n\n// Vue3\nconst props = defineProps<{\n status: 'success' | 'warning' | 'error';\n count?: number;\n}>();",
35
- "incorrectExample": "props: ['status', 'count']"
36
- },
37
- {
38
- "id": "vue-props-camelcase",
39
- "title": "Props 命名使用 camelCase",
40
- "description": "在声明 props 时,其命名应该始终使用 camelCase。",
41
- "correctExample": "props: {\n greetingText: String\n}",
42
- "incorrectExample": "props: {\n 'greeting-text': String\n}"
43
- },
44
- {
45
- "id": "vue-event-kebabcase",
46
- "title": "事件名使用 kebab-case",
47
- "description": "事件名应该使用 kebab-case 命名。",
48
- "correctExample": "this.$emit('item-click', item);\nemit('update-value', newValue);",
49
- "incorrectExample": "this.$emit('itemClick', item);\nemit('updateValue', newValue);"
50
- },
51
- {
52
- "id": "vue-self-closing",
53
- "title": "组件标签自闭合",
54
- "description": "没有内容的组件应该自闭合。",
55
- "correctExample": "<MyComponent />\n<ne-button type=\"primary\" />",
56
- "incorrectExample": "<MyComponent></MyComponent>\n<ne-button type=\"primary\"></ne-button>"
57
- },
58
- {
59
- "id": "vue-multi-attribute",
60
- "title": "多属性换行",
61
- "description": "当组件有多个属性时,应该每个属性占一行。",
62
- "correctExample": "<ne-field\n v-model=\"formData.name\"\n label=\"姓名\"\n placeholder=\"请输入姓名\"\n required\n :rules=\"nameRules\"\n/>",
63
- "incorrectExample": "<ne-field v-model=\"formData.name\" label=\"姓名\" placeholder=\"请输入姓名\" required :rules=\"nameRules\" />"
64
- },
65
- {
66
- "id": "vue-script-setup",
67
- "title": "使用 script setup (Vue3)",
68
- "description": "Vue3 项目推荐使用 <script setup> 语法。",
69
- "correctExample": "<script setup>\nimport { ref, computed } from 'vue';\n\nconst count = ref(0);\nconst double = computed(() => count.value * 2);\n</script>",
70
- "incorrectExample": "<script>\nimport { ref, computed, defineComponent } from 'vue';\n\nexport default defineComponent({\n setup() {\n const count = ref(0);\n return { count };\n }\n});\n</script>"
71
- },
72
- {
73
- "id": "vue-code-order",
74
- "title": "响应式数据声明顺序",
75
- "description": "按照以下顺序组织代码:props/emits → refs → computed → watch → 生命周期 → methods",
76
- "correctExample": "<script setup>\n// 1. Props 和 Emits\nconst props = defineProps<{ title: string }>();\nconst emit = defineEmits<{ (e: 'update', value: string): void }>();\n\n// 2. 响应式数据\nconst count = ref(0);\n\n// 3. 计算属性\nconst total = computed(() => count.value);\n\n// 4. 侦听器\nwatch(count, (newVal) => { });\n\n// 5. 生命周期\nonMounted(() => { });\n\n// 6. 方法\nfunction loadData() { }\n</script>",
77
- "incorrectExample": "// 代码顺序混乱"
78
- },
79
- {
80
- "id": "vue-style-external",
81
- "title": "样式必须剥离到外部文件",
82
- "description": "Vue 组件的样式必须剥离到独立的 SCSS 文件中,通过 @import 方式引入。",
83
- "correctExample": "<style lang=\"scss\" scoped>\n@import './css/login.scss';\n</style>",
84
- "incorrectExample": "<style lang=\"scss\" scoped>\n.login_page {\n // 大量样式代码直接写在 .vue 文件中\n}\n</style>"
85
- },
86
- {
87
- "id": "vue-style-scoped",
88
- "title": "style 标签必须使用 scoped",
89
- "description": "为避免样式污染,<style> 标签必须添加 scoped 属性。",
90
- "correctExample": "<style lang=\"scss\" scoped>\n@import './css/user-profile.scss';\n</style>",
91
- "incorrectExample": "<style lang=\"scss\">\n@import './css/user-profile.scss';\n</style>"
92
- },
93
- {
94
- "id": "vue-no-header-refactor",
95
- "title": "重构页面时不添加导航栏",
96
- "description": "重构现有页面时,不需要添加 em-header 或 nav-bar 导航栏组件。导航栏由框架或原生容器统一管理。",
97
- "correctExample": "<template>\n <div class=\"page-container\">\n <div class=\"content\">\n <em-cell title=\"用户信息\" />\n </div>\n </div>\n</template>",
98
- "incorrectExample": "<template>\n <div class=\"page-container\">\n <em-header title=\"页面标题\" />\n <div class=\"content\">\n <em-cell title=\"用户信息\" />\n </div>\n </div>\n</template>"
99
- },
100
- {
101
- "id": "vue-no-complex-template",
102
- "title": "避免在模板中使用复杂表达式",
103
- "description": "复杂的逻辑应该使用计算属性,而不是直接写在模板中。",
104
- "correctExample": "<template>\n <div>{{ activeItemNames }}</div>\n</template>\n\n<script setup>\nconst activeItemNames = computed(() =>\n items.value.filter(i => i.active).map(i => i.name).join(', ')\n);\n</script>",
105
- "incorrectExample": "<template>\n <div>{{ items.filter(i => i.active).map(i => i.name).join(', ') }}</div>\n</template>"
106
- },
107
- {
108
- "id": "vue-no-mutate-props",
109
- "title": "避免直接修改 Props",
110
- "description": "不要直接修改 props,应该使用 emit 通知父组件。",
111
- "correctExample": "emit('update:value', newValue);",
112
- "incorrectExample": "props.value = newValue;"
113
- },
114
- {
115
- "id": "vue-field-clickable",
116
- "title": "输入框交互规范",
117
- "description": "当输入框为 readonly 但需要点击触发操作时,必须同时添加 is-link 和 clickable 属性。",
118
- "correctExample": "<em-field\n v-model=\"date\"\n readonly\n clickable\n is-link\n label=\"选择日期\"\n @click=\"showDatePicker\"\n/>",
119
- "incorrectExample": "<em-field\n v-model=\"date\"\n readonly\n label=\"选择日期\"\n @click=\"showDatePicker\"\n/>"
120
- }
121
- ]
122
- }
File without changes