m8-mcp-server 1.0.4 → 1.0.6
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/README.md +184 -14
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +1 -1
- package/dist/docs/apis.d.ts +1 -1
- package/dist/docs/apis.js +1 -1
- package/dist/docs/components.d.ts +1 -1
- package/dist/docs/components.js +1 -1
- package/dist/docs/index.d.ts +1 -1
- package/dist/docs/index.js +1 -1
- package/dist/docs/loader.d.ts +1 -1
- package/dist/docs/loader.js +1 -1
- package/dist/docs/search.d.ts +1 -1
- package/dist/docs/search.js +1 -1
- package/dist/docs/standards.d.ts +1 -1
- package/dist/docs/standards.js +1 -1
- package/dist/docs/utils.d.ts +1 -1
- package/dist/docs/utils.js +1 -1
- package/dist/generator/header.d.ts +1 -1
- package/dist/generator/header.js +1 -1
- package/dist/generator/index.d.ts +1 -1
- package/dist/generator/index.js +1 -1
- package/dist/generator/vue-template.d.ts +22 -1
- package/dist/generator/vue-template.d.ts.map +1 -1
- package/dist/generator/vue-template.js +498 -34
- package/dist/generator/vue-template.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/recommend/index.d.ts +1 -1
- package/dist/recommend/index.js +1 -1
- package/dist/tools/generate-code.d.ts +1 -1
- package/dist/tools/generate-code.js +1 -1
- package/dist/tools/get-api-info.d.ts +1 -1
- package/dist/tools/get-api-info.js +1 -1
- package/dist/tools/get-coding-standard.d.ts +1 -1
- package/dist/tools/get-coding-standard.js +1 -1
- package/dist/tools/get-component-info.d.ts +1 -1
- package/dist/tools/get-component-info.js +1 -1
- package/dist/tools/get-util-info.d.ts +1 -1
- package/dist/tools/get-util-info.js +1 -1
- package/dist/tools/index.d.ts +1 -1
- package/dist/tools/index.js +1 -1
- package/dist/tools/recommend-solution.d.ts +1 -1
- package/dist/tools/recommend-solution.js +1 -1
- package/dist/tools/search-docs.d.ts +1 -1
- package/dist/tools/search-docs.js +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.js +1 -1
- package/package.json +4 -4
- package/resources/cases/.gitkeep +0 -0
- package/resources/cases/form-submit-vue2.json +0 -15
- package/resources/cases/index.json +0 -8
- package/resources/cases/list-detail-vue2.json +0 -27
- package/resources/components/.gitkeep +0 -0
- package/resources/components/button.json +0 -74
- package/resources/components/cell.json +0 -69
- package/resources/components/field.json +0 -88
- package/resources/components/index.json +0 -72
- package/resources/standards/.gitkeep +0 -0
- package/resources/standards/css.json +0 -108
- package/resources/standards/javascript.json +0 -129
- package/resources/standards/project-structure.json +0 -101
- package/resources/standards/vue.json +0 -122
- package/resources/utils/.gitkeep +0 -0
- package/resources/utils/ajax.json +0 -76
- package/resources/utils/common.json +0 -129
- package/resources/utils/index.json +0 -7
- package/resources/utils/string.json +0 -112
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "field",
|
|
3
|
-
"name": "em-field",
|
|
4
|
-
"title": "输入框",
|
|
5
|
-
"description": "表单中的输入框组件,支持多种类型和样式。",
|
|
6
|
-
"props": [
|
|
7
|
-
{ "name": "v-model", "type": "number/string", "default": "-", "required": false, "description": "当前输入的值" },
|
|
8
|
-
{ "name": "label", "type": "string", "default": "-", "required": false, "description": "输入框左侧文本" },
|
|
9
|
-
{ "name": "name", "type": "string", "default": "-", "required": false, "description": "名称,提交表单的标识符" },
|
|
10
|
-
{ "name": "type", "type": "string", "default": "text", "required": false, "description": "输入框类型,可选值为 tel、digit、number、textarea、password 等" },
|
|
11
|
-
{ "name": "size", "type": "string", "default": "-", "required": false, "description": "大小,可选值为 large" },
|
|
12
|
-
{ "name": "maxlength", "type": "number/string", "default": "-", "required": false, "description": "输入的最大字符数" },
|
|
13
|
-
{ "name": "placeholder", "type": "string", "default": "-", "required": false, "description": "输入框占位提示文字" },
|
|
14
|
-
{ "name": "placeholder-style", "type": "string", "default": "color: #b8becc;", "required": false, "description": "指定 placeholder 的样式" },
|
|
15
|
-
{ "name": "border", "type": "boolean", "default": "true", "required": false, "description": "是否显示内边框" },
|
|
16
|
-
{ "name": "disabled", "type": "boolean", "default": "false", "required": false, "description": "是否禁用输入框" },
|
|
17
|
-
{ "name": "readonly", "type": "boolean", "default": "false", "required": false, "description": "是否只读" },
|
|
18
|
-
{ "name": "colon", "type": "boolean", "default": "false", "required": false, "description": "是否在 label 后面添加冒号" },
|
|
19
|
-
{ "name": "required", "type": "boolean", "default": "false", "required": false, "description": "是否显示表单必填星号" },
|
|
20
|
-
{ "name": "center", "type": "boolean", "default": "false", "required": false, "description": "是否使内容垂直居中" },
|
|
21
|
-
{ "name": "clearable", "type": "boolean", "default": "false", "required": false, "description": "是否启用清除图标" },
|
|
22
|
-
{ "name": "clickable", "type": "boolean", "default": "false", "required": false, "description": "是否开启点击反馈" },
|
|
23
|
-
{ "name": "is-link", "type": "boolean", "default": "false", "required": false, "description": "是否展示右侧箭头并开启点击反馈" },
|
|
24
|
-
{ "name": "autofocus", "type": "boolean", "default": "false", "required": false, "description": "是否自动聚焦" },
|
|
25
|
-
{ "name": "show-word-limit", "type": "boolean", "default": "false", "required": false, "description": "是否显示字数统计" },
|
|
26
|
-
{ "name": "error", "type": "boolean", "default": "false", "required": false, "description": "是否将输入内容标红" },
|
|
27
|
-
{ "name": "error-message", "type": "string", "default": "-", "required": false, "description": "底部错误提示文案" },
|
|
28
|
-
{ "name": "formatter", "type": "Function", "default": "-", "required": false, "description": "输入内容格式化函数" },
|
|
29
|
-
{ "name": "format-trigger", "type": "string", "default": "onChange", "required": false, "description": "格式化函数触发的时机,可选值为 onBlur" },
|
|
30
|
-
{ "name": "label-width", "type": "number/string", "default": "96px", "required": false, "description": "左侧文本宽度" },
|
|
31
|
-
{ "name": "label-align", "type": "string", "default": "left", "required": false, "description": "左侧文本对齐方式,可选值为 center、right" },
|
|
32
|
-
{ "name": "input-align", "type": "string", "default": "left", "required": false, "description": "输入框对齐方式,可选值为 center、right、vertical" },
|
|
33
|
-
{ "name": "autosize", "type": "boolean/object", "default": "false", "required": false, "description": "是否自适应内容高度,只对 textarea 有效" },
|
|
34
|
-
{ "name": "left-icon", "type": "string", "default": "-", "required": false, "description": "左侧图标名称或图片链接" },
|
|
35
|
-
{ "name": "right-icon", "type": "string", "default": "-", "required": false, "description": "右侧图标名称或图片链接" },
|
|
36
|
-
{ "name": "rules", "type": "Rule[]", "default": "-", "required": false, "description": "表单校验规则" },
|
|
37
|
-
{ "name": "basic", "type": "boolean", "default": "false", "required": false, "description": "是否使用基座风格样式" }
|
|
38
|
-
],
|
|
39
|
-
"events": [
|
|
40
|
-
{ "name": "input", "parameters": "value: string", "description": "输入框内容变化时触发" },
|
|
41
|
-
{ "name": "focus", "parameters": "event: Event", "description": "输入框获得焦点时触发" },
|
|
42
|
-
{ "name": "blur", "parameters": "event: Event", "description": "输入框失去焦点时触发" },
|
|
43
|
-
{ "name": "clear", "parameters": "event: Event", "description": "点击清除按钮时触发" },
|
|
44
|
-
{ "name": "click", "parameters": "event: Event", "description": "点击 Field 时触发" },
|
|
45
|
-
{ "name": "click-input", "parameters": "event: Event", "description": "点击输入区域时触发" },
|
|
46
|
-
{ "name": "click-left-icon", "parameters": "event: Event", "description": "点击左侧图标时触发" },
|
|
47
|
-
{ "name": "click-right-icon", "parameters": "event: Event", "description": "点击右侧图标时触发" }
|
|
48
|
-
],
|
|
49
|
-
"slots": [
|
|
50
|
-
{ "name": "label", "description": "自定义输入框 label 标签" },
|
|
51
|
-
{ "name": "input", "description": "自定义输入框" },
|
|
52
|
-
{ "name": "leftIcon", "description": "自定义输入框头部图标" },
|
|
53
|
-
{ "name": "rightIcon", "description": "自定义输入框尾部图标" },
|
|
54
|
-
{ "name": "button", "description": "自定义输入框尾部按钮" },
|
|
55
|
-
{ "name": "extra", "description": "自定义输入框最右侧的额外内容" }
|
|
56
|
-
],
|
|
57
|
-
"examples": {
|
|
58
|
-
"vue2": [
|
|
59
|
-
{
|
|
60
|
-
"title": "基础用法",
|
|
61
|
-
"code": "<em-cell-group>\n <em-field v-model=\"value\" label=\"文本\" placeholder=\"请输入用户名\" />\n</em-cell-group>\n\n<script>\nexport default {\n data() {\n return {\n value: ''\n };\n }\n};\n</script>",
|
|
62
|
-
"description": "通过 v-model 双向绑定输入框的值"
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
"title": "基座风格",
|
|
66
|
-
"code": "<em-cell-group>\n <em-field label=\"横向必填项\" basic required is-link placeholder=\"请输入\" v-model=\"value\"></em-field>\n</em-cell-group>",
|
|
67
|
-
"description": "通过 basic 设置基座风格的样式"
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
"title": "自定义类型",
|
|
71
|
-
"code": "<em-field v-model=\"tel\" type=\"tel\" label=\"手机号\" />\n<em-field v-model=\"number\" type=\"number\" label=\"整数\" />\n<em-field v-model=\"password\" type=\"password\" label=\"密码\" />",
|
|
72
|
-
"description": "根据 type 属性定义不同类型的输入框"
|
|
73
|
-
}
|
|
74
|
-
],
|
|
75
|
-
"vue3": [
|
|
76
|
-
{
|
|
77
|
-
"title": "基础用法",
|
|
78
|
-
"code": "<em-cell-group>\n <em-field v-model=\"value\" label=\"文本\" placeholder=\"请输入用户名\" />\n</em-cell-group>\n\n<script setup>\nimport { ref } from 'vue';\nconst value = ref('');\n</script>",
|
|
79
|
-
"description": "通过 v-model 双向绑定输入框的值"
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
"title": "基座风格",
|
|
83
|
-
"code": "<em-cell-group>\n <em-field label=\"横向必填项\" basic required is-link placeholder=\"请输入\" v-model=\"value\"></em-field>\n</em-cell-group>\n\n<script setup>\nimport { ref } from 'vue';\nconst value = ref('');\n</script>",
|
|
84
|
-
"description": "通过 basic 设置基座风格的样式"
|
|
85
|
-
}
|
|
86
|
-
]
|
|
87
|
-
}
|
|
88
|
-
}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"components": [
|
|
3
|
-
{ "id": "actionsheet", "name": "em-actionsheet", "title": "动作面板", "file": "actionsheet.json" },
|
|
4
|
-
{ "id": "amap", "name": "em-amap", "title": "地图", "file": "amap.json" },
|
|
5
|
-
{ "id": "button", "name": "em-button", "title": "按钮", "file": "button.json" },
|
|
6
|
-
{ "id": "cell", "name": "em-cell", "title": "单元格", "file": "cell.json" },
|
|
7
|
-
{ "id": "checkbox", "name": "em-checkbox", "title": "复选框", "file": "checkbox.json" },
|
|
8
|
-
{ "id": "circle", "name": "em-circle", "title": "环形进度条", "file": "circle.json" },
|
|
9
|
-
{ "id": "datepicker", "name": "em-datepicker", "title": "日期选择", "file": "datepicker.json" },
|
|
10
|
-
{ "id": "field", "name": "em-field", "title": "输入框", "file": "field.json" },
|
|
11
|
-
{ "id": "form", "name": "em-form", "title": "表单", "file": "form.json" },
|
|
12
|
-
{ "id": "header", "name": "em-header", "title": "头部导航栏", "file": "header.json" },
|
|
13
|
-
{ "id": "icon", "name": "em-icon", "title": "图标", "file": "icon.json" },
|
|
14
|
-
{ "id": "loading", "name": "em-loading", "title": "加载", "file": "loading.json" },
|
|
15
|
-
{ "id": "noticebar", "name": "em-noticebar", "title": "通知栏", "file": "noticebar.json" },
|
|
16
|
-
{ "id": "numberkeyboard", "name": "em-numberkeyboard", "title": "数字键盘", "file": "numberkeyboard.json" },
|
|
17
|
-
{ "id": "pagination", "name": "em-pagination", "title": "分页", "file": "pagination.json" },
|
|
18
|
-
{ "id": "panel", "name": "em-panel", "title": "面板", "file": "panel.json" },
|
|
19
|
-
{ "id": "passwordinput", "name": "em-passwordinput", "title": "密码输入框", "file": "passwordinput.json" },
|
|
20
|
-
{ "id": "picker", "name": "em-picker", "title": "选择器", "file": "picker.json" },
|
|
21
|
-
{ "id": "popup", "name": "em-popup", "title": "弹出层", "file": "popup.json" },
|
|
22
|
-
{ "id": "progress", "name": "em-progress", "title": "进度条", "file": "progress.json" },
|
|
23
|
-
{ "id": "radio", "name": "em-radio", "title": "单选框", "file": "radio.json" },
|
|
24
|
-
{ "id": "rate", "name": "em-rate", "title": "评分", "file": "rate.json" },
|
|
25
|
-
{ "id": "search", "name": "em-search", "title": "搜索", "file": "search.json" },
|
|
26
|
-
{ "id": "slider", "name": "em-slider", "title": "滑块", "file": "slider.json" },
|
|
27
|
-
{ "id": "stepper", "name": "em-stepper", "title": "步进器", "file": "stepper.json" },
|
|
28
|
-
{ "id": "swipecell", "name": "em-swipecell", "title": "滑动单元格", "file": "swipecell.json" },
|
|
29
|
-
{ "id": "switch", "name": "em-switch", "title": "开关", "file": "switch.json" },
|
|
30
|
-
{ "id": "switchcell", "name": "em-switchcell", "title": "开关单元格", "file": "switchcell.json" },
|
|
31
|
-
{ "id": "tag", "name": "em-tag", "title": "标记", "file": "tag.json" },
|
|
32
|
-
{ "id": "treeselect", "name": "em-treeselect", "title": "分类选择", "file": "treeselect.json" },
|
|
33
|
-
{ "id": "uploader", "name": "em-uploader", "title": "文件上传", "file": "uploader.json" },
|
|
34
|
-
{ "id": "verifycode", "name": "em-verifycode", "title": "验证码", "file": "verifycode.json" },
|
|
35
|
-
{ "id": "minirefresh", "name": "em-minirefresh", "title": "下拉刷新", "file": "minirefresh.json" },
|
|
36
|
-
{ "id": "layout", "name": "em-layout", "title": "布局", "file": "layout.json" },
|
|
37
|
-
{ "id": "image", "name": "em-image", "title": "图片", "file": "image.json" },
|
|
38
|
-
{ "id": "toast", "name": "em-toast", "title": "轻提示", "file": "toast.json" },
|
|
39
|
-
{ "id": "calendar", "name": "em-calendar", "title": "日历", "file": "calendar.json" },
|
|
40
|
-
{ "id": "area", "name": "em-area", "title": "省市区选择", "file": "area.json" },
|
|
41
|
-
{ "id": "tab", "name": "em-tab", "title": "标签页", "file": "tab.json" },
|
|
42
|
-
{ "id": "dialog", "name": "em-dialog", "title": "弹出框", "file": "dialog.json" },
|
|
43
|
-
{ "id": "dropdownmenu", "name": "em-dropdownmenu", "title": "下拉菜单", "file": "dropdownmenu.json" },
|
|
44
|
-
{ "id": "notify", "name": "em-notify", "title": "消息通知", "file": "notify.json" },
|
|
45
|
-
{ "id": "overlay", "name": "em-overlay", "title": "遮罩层", "file": "overlay.json" },
|
|
46
|
-
{ "id": "collapse", "name": "em-collapse", "title": "折叠面板", "file": "collapse.json" },
|
|
47
|
-
{ "id": "grid", "name": "em-grid", "title": "宫格", "file": "grid.json" },
|
|
48
|
-
{ "id": "countdown", "name": "em-countdown", "title": "倒计时", "file": "countdown.json" },
|
|
49
|
-
{ "id": "divider", "name": "em-divider", "title": "分割线", "file": "divider.json" },
|
|
50
|
-
{ "id": "empty", "name": "em-empty", "title": "空状态", "file": "empty.json" },
|
|
51
|
-
{ "id": "imagepreview", "name": "em-imagepreview", "title": "图片预览", "file": "imagepreview.json" },
|
|
52
|
-
{ "id": "lazyload", "name": "em-lazyload", "title": "懒加载", "file": "lazyload.json" },
|
|
53
|
-
{ "id": "skeleton", "name": "em-skeleton", "title": "骨架屏", "file": "skeleton.json" },
|
|
54
|
-
{ "id": "steps", "name": "em-steps", "title": "步骤条", "file": "steps.json" },
|
|
55
|
-
{ "id": "sticky", "name": "em-sticky", "title": "粘性布局", "file": "sticky.json" },
|
|
56
|
-
{ "id": "indexbar", "name": "em-indexbar", "title": "索引栏", "file": "indexbar.json" },
|
|
57
|
-
{ "id": "sidebar", "name": "em-sidebar", "title": "侧边导航", "file": "sidebar.json" },
|
|
58
|
-
{ "id": "tabbar", "name": "em-tabbar", "title": "标签栏", "file": "tabbar.json" },
|
|
59
|
-
{ "id": "badge", "name": "em-badge", "title": "徽标", "file": "badge.json" },
|
|
60
|
-
{ "id": "popover", "name": "em-popover", "title": "气泡弹出框", "file": "popover.json" },
|
|
61
|
-
{ "id": "cascader", "name": "em-cascader", "title": "级联选择", "file": "cascader.json" },
|
|
62
|
-
{ "id": "selectperson", "name": "em-selectperson", "title": "选人组件", "file": "selectperson.json" },
|
|
63
|
-
{ "id": "swipe", "name": "em-swipe", "title": "轮播", "file": "swipe.json" },
|
|
64
|
-
{ "id": "easycalendar", "name": "em-easycalendar", "title": "日历", "file": "easycalendar.json" },
|
|
65
|
-
{ "id": "qrcode", "name": "em-qrcode", "title": "二维码", "file": "qrcode.json" },
|
|
66
|
-
{ "id": "imagescale", "name": "em-imagescale", "title": "图片裁剪", "file": "imagescale.json" },
|
|
67
|
-
{ "id": "dragsort", "name": "em-dragsort", "title": "拖拽排序", "file": "dragsort.json" },
|
|
68
|
-
{ "id": "chart", "name": "em-chart", "title": "图表", "file": "chart.json" },
|
|
69
|
-
{ "id": "rtc", "name": "em-rtc", "title": "音视频", "file": "rtc.json" },
|
|
70
|
-
{ "id": "table", "name": "em-table", "title": "表格", "file": "table.json" }
|
|
71
|
-
]
|
|
72
|
-
}
|
|
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
|
-
}
|