项目搭建规范
一、代码规范
1.1. 新建 .editorconfig 文件
# http://editorconfig.org
root = true
[*] # 表示所有文件适用
charset = utf-8 # 设置文件字符集为 utf-8
indent_style = space # 缩进风格(tab | space)
indent_size = 2 # 缩进大小
end_of_line = lf # 控制换行类型(lf | cr | crlf)
trim_trailing_whitespace = true # 去除行首的任意空白字符
insert_final_newline = true # 始终在文件末尾插入一个新行
[*.md] # 表示仅 md 文件适用以下规则
max_line_length = off
trim_trailing_whitespace = false
VSCode 需要安装一个插件:EditorConfig for VS Code
1.2. 使用 prettier 工具
Prettier 是一款强大的代码格式化工具,基本上前端能用到的文件格式它都可以搞定,是当下最流行的代码格式化工具。
- 安装
prettier
npm install prettier -D
- 新建
.prettierrc文件:
- useTabs:使用tab缩进还是空格缩进,选择false;
- tabWidth:tab是空格的情况下,是几个空格,选择2个;
- printWidth:当行字符的长度,推荐80,也有人喜欢100或者120;
- singleQuote:使用单引号还是双引号,选择true,使用单引号;
- trailingComma:在多行输入的尾逗号是否添加,设置为
none; - semi:语句末尾是否要加分号,默认值true,选择false表示不加;
{
"useTabs": false,
"tabWidth": 2,
"printWidth": 80,
"singleQuote": true,
"trailingComma": "es5",
"semi": true
}
- 创建
.prettierignore忽略文件
/dist/*
.local
.output.js
/node_modules/**
**/*.svg
**/*.sh
shims-vue.d.ts
/public/*
-
VSCode需要安装prettier的插件 -
配置一次性修改的命令;在
package.json中配置一个scripts:
// 执行 npm run prettier 即可格式化所有文件
"prettier": "prettier --write ."
1.3. 使用 ESLint 检测
- 在前面创建项目的时候,我们就选择了
ESLint,所以Vue会默认帮助我们配置需要的ESLint环境。 VSCode需要安装ESLint插件:- 解决
Eslint和prettier冲突的问题:
安装插件:eslint-plugin-prettier eslint-config-prettier
// vue在创建项目时,如果选择prettier,那么这两个插件会自动安装
npm i eslint-plugin-prettier eslint-config-prettier -D
在 .eslintrc 文件中添加 prettier 插件:
extends: [
"plugin:vue/vue3-essential",
"eslint:recommended",
"@vue/typescript/recommended",
"@vue/prettier",
"@vue/prettier/@typescript-eslint",
'plugin:prettier/recommended' // 会覆盖前面几个的格式
],
1.4. git Husky 和 eslint
虽然项目使用 eslint 了,但不能保证组员提交代码之前都将 eslint 中的问题解决掉:故在组员执行 git commit 命令的时候对其进行校验,如果不符合 eslint 规范,那么自动通过规范进行修复;
我们可以通过 Husky 工具实现这一点:
husky是一个git hook工具,可以帮助我们触发git提交的各个阶段:pre-commit、commit-msg、pre-push
执行自动配置命令:
// 注意:需把 powershell 换成 cmd,再执行该命令
npx husky-init && npm install
这里会做三件事:
- 安装
husky相关的依赖:
- 在项目目录下创建
.husky文件夹:
npx huksy install
- 在
package.json中添加一个脚本:
接下来,我们需要去完成一个操作:在进行 commit 时,执行 lint 脚本:
这个时候我们执行 git commit 的时候会自动对代码进行 lint 校验。
1.5. git commit 规范
| Type | 作用 |
|---|---|
| feat | 新增特性 (feature) |
| fix | 修复 Bug(bug fix) |
| docs | 修改文档 (documentation) |
| style | 代码格式修改(white-space, formatting, missing semi colons, etc) |
| refactor | 代码重构(refactor) |
| perf | 改善性能(A code change that improves performance) |
| test | 测试(when adding missing tests) |
| build | 变更项目构建或外部依赖(例如 scopes: webpack、gulp、npm 等) |
| ci | 更改持续集成软件的配置文件和 package 中的 scripts 命令,例如 scopes: Travis, Circle 等 |
| chore | 变更构建流程或辅助工具(比如更改测试环境) |
| revert | 代码回退 |
分割线---------------------------------------------------------------
关于登录后的逻辑处理
一旦用户登录成功,逻辑部分的处理放在哪个地方合适呢?
- 登录的逻辑(网络请求,拿到数据后的处理)
- 数据的保存到某一个位置
- 发送其他的请求(请求当前用户的信息)
- 拿到用户的菜单
- 跳转到首页
注意:如此众多的逻辑交给首页处理是不合适的,我们可以交给 vuex 来管理。
对 Form 表单进行二次封装
目的:其他人在使用时,只需注册、引用
Form组件,传入配置即可。
支持如下配置
支持以下配置,即有这几种数据类型。故可设计
Form的interface如下:
type IFormType = 'input' | 'password' | 'select' | 'datepicker'
export interface IFormItem {
type: IFormType
label: string
rules?: any[]
placeholder?: any
// 针对select
options?: any[]
// 针对特殊的属性
otherOptions?: any
}
export interface IForm {
formItems: IFormItem[]
labelWidth?: string
colLayout: any
itemLayout: any
}
- labelWidth:
label的宽度
labelWidth: '120px' // 设置 label 的宽度为 120px
- itemLayout:
item的左右宽度
itemLayout: {
padding: '10px 40px'
}
- colLayout:
FormItem项随着浏览器的宽度变化而变化。即响应式栅格数或者栅格属性对象
colLayout: {
span: 8
},
- formItems:配置每一项
item的类型。
formItems: [
{
type: 'input',
label: 'id',
placeholder: '请输入id',
rule: [{ required: false, message: '请输入id', trigger: 'change' }], // 当前规则
},
{
type: 'input',
label: '用户名',
placeholder: '请输入用户名'
},
{
type: 'password',
label: '密码',
placeholder: '请输入密码'
},
{
type: 'select',
label: '喜欢的运动',
placeholder: '请选择喜欢的运动',
options: [
{ title: '篮球', value: 'basketball' },
{ title: '足球', value: 'football' }
]
},
{
type: 'datepicker',
label: '创建时间',
otherOptions: {
startPlaceholder: '开始时间',
endPlaceholder: '结束时间',
type: 'daterange'
}
},
]
}
bug修复
bug描述:任意选中一个二级菜单进行刷新,左侧菜单栏始终选中用户管理。
- bug原因:
<el-menu default-active="2"></el-menu>,恰好用户管理的id为2 - bug解决:
default-active的值应该动态获取。 - 解决思路:获取
currentPath,并与userMenus中的path进行匹配,得到menuId
代码实现:通过
useRoute获取当前路径,并在store中取出userMenus,使用递归方法pathMapToMenu获取当前路径的menuId.
- 获取
currentPath
import { useRouter, useRoute } from 'vue-router'
const route = useRoute()
const currentPath = route.path
- 获取
userMenus
import { useStore } from '@/store'
const store = useStore()
const userMenus = computed(() => store.state.login.userMenus)
console.log(userMenus.value)
- 匹配方法
pathMapToMenu
export function pathMapToMenu(userMenus: any[], currentPath: string): any {
for (const menu of userMenus) {
if (menu.type === 1) {
const findMenu = pathMapToMenu(menu.children ?? [], currentPath)
if (findMenu) {
return findMenu
}
} else if (menu.type === 2 && menu.url === currentPath) {
return menu
}
}
}
对面包屑的二次封装
使用者传入一个对象数组,包含 name 和 path 属性,即可生成可点击的面包屑。
- 使用过程
<jn-breadcrumb :breadcrumbs="breadcrumbs" />
- 封装过程
// 获取当前路径
import { useRoute } from 'vue-router'
const route = useRoute()
const currentPath = route.path
// 获取菜单
import { useStore } from '@/store'
const store = useStore()
const userMenus = store.state.login.userMenus
// 传入 userMenus, currentPath 得到一个包含 name 和 path 属性的对象数组
const breadcrumbs = pathMapBreadcrumbs(userMenus, currentPath)
实现 pathMapBreadcrumbs
export function pathMapBreadcrumbs(userMenus: any[], currentPath: string) {
const breadcrumbs: IBreadcrumb[] = []
pathMapToMenu(userMenus, currentPath, breadcrumbs)
return breadcrumbs
}
// /main/system/role -> type === 2 对应menu
export function pathMapToMenu(
userMenus: any[],
currentPath: string,
breadcrumbs?: IBreadcrumb[]
): any {
for (const menu of userMenus) {
if (menu.type === 1) {
const findMenu = pathMapToMenu(menu.children ?? [], currentPath)
if (findMenu) {
breadcrumbs?.push({ name: menu.name })
breadcrumbs?.push({ name: findMenu.name })
return findMenu
}
} else if (menu.type === 2 && menu.url === currentPath) {
return menu
}
}
}
一些 bugs
PS D:\_B.study\_B2.front-end\_11.vue3-ts\bms-vue3-ts> npm run serve
> bms-vue3-ts@0.1.0 serve D:\_B.study\_B2.front-end\_11.vue3-ts\bms-vue3-ts
> vue-cli-service serve
ERROR Error: Cannot find module 'node:module'
Require stack:
- D:\_B.study\_B2.front-end\_11.vue3-ts\bms-vue3-ts\node_modules\mlly\dist\index.cjs
- D:\_B.study\_B2.front-end\_11.vue3-ts\bms-vue3-ts\node_modules\unimport\dist\shared\unimport.a775c700.cjs
- D:\_B.study\_B2.front-end\_11.vue3-ts\bms-vue3-ts\node_modules\unimport\dist\addons.cjs
- D:\_B.study\_B2.front-end\_11.vue3-ts\bms-vue3-ts\node_modules\unplugin-auto-import\dist\chunk-HA63LRAS.cjs
- D:\_B.study\_B2.front-end\_11.vue3-ts\bms-vue3-ts\node_modules\unplugin-auto-import\dist\webpack.cjs
- D:\_B.study\_B2.front-end\_11.vue3-ts\bms-vue3-ts\vue.config.js
- D:\_B.study\_B2.front-end\_11.vue3-ts\bms-vue3-ts\node_modules\@vue\cli-shared-utils\lib\module.js
- D:\_B.study\_B2.front-end\_11.vue3-ts\bms-vue3-ts\node_modules\@vue\cli-shared-utils\index.js
- D:\_B.study\_B2.front-end\_11.vue3-ts\bms-vue3-ts\node_modules\@vue\cli-service\bin\vue-cli-service.js
Error: Cannot find module 'node:module'
- D:\_B.study\_B2.front-end\_11.vue3-ts\bms-vue3-ts\node_modules\unplugin-auto-import\dist\chunk-HA63LRAS.cjs
- D:\_B.study\_B2.front-end\_11.vue3-ts\bms-vue3-ts\node_modules\unplugin-auto-import\dist\webpack.cjs
- D:\_B.study\_B2.front-end\_11.vue3-ts\bms-vue3-ts\vue.config.js
- D:\_B.study\_B2.front-end\_11.vue3-ts\bms-vue3-ts\node_modules\@vue\cli-shared-utils\lib\module.js
- D:\_B.study\_B2.front-end\_11.vue3-ts\bms-vue3-ts\node_modules\@vue\cli-shared-utils\index.js
- D:\_B.study\_B2.front-end\_11.vue3-ts\bms-vue3-ts\node_modules\@vue\cli-service\bin\vue-cli-service.js
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:889:15)
at Function.Module._load (internal/modules/cjs/loader.js:745:27)
at Module.require (internal/modules/cjs/loader.js:961:19)
at require (internal/modules/cjs/helpers.js:92:18)
at Object.<anonymous> (D:\_B.study\_B2.front-end\_11.vue3-ts\bms-vue3-ts\node_modules\mlly\dist\index.cjs:4:21)
at Module._compile (internal/modules/cjs/loader.js:1072:14)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1101:10)
at Module.load (internal/modules/cjs/loader.js:937:32)
at Function.Module._load (internal/modules/cjs/loader.js:778:12)
at Module.require (internal/modules/cjs/loader.js:961:19)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! bms-vue3-ts@0.1.0 serve: `vue-cli-service serve`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the bms-vue3-ts@0.1.0 serve script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\易朝松\AppData\Roaming\npm-cache\_logs\2023-01-31T01_11_07_068Z-debug.log