代码的最终归宿都是屎山罢了,而一份适用于团队的代码规范,可以极大延缓屎山的堆积速度。
文中部分标注了删除线的,代表eslint已开启了相关配置,vscode会自动做出提示。
本文在线 思维导图 地址
项目工程规范
上图是整体项目目录,对于有点经验的正常前端开发人员,讲道理看文件名字应该都能基本理清用途。所以对我们团队内部的项目工程规范来说,将着重于文件命名规范和存在位置。
使用 vue-generate-component 插件,在控制台执行ovgc demo-page,将自动创建如下文件
插件地址 fork自 地址
无css样式时,删除scss文件,无单元测试时,删除spec文件。
- 对于服务命名要求词尾统一加Serivce
- 统一在src / api / index.ts文件中 export
- 统一从 ‘@/api’ 下 import
使用时,公共方法统一从 '@/utils’中 import
import { fuzzyQueryStr } from '@/utils';
而特殊工具类,从各自所属位置import
import { axiosRequest } from '@/utils/axios-request';
7、路由按照模块进行区分,放在src/router/modules文件夹中
8、vuex按照大模块进行拆分,放在src/store/modules文件夹中,另外仓储服务输出时,要求使用大驼峰命名,与一般的服务类进行区分。
export const PermissionModule = getModule(Permission);
9、i18n翻译文件,以资源对象进行分割,该对象所有相关的文案都放在该对象下,不允许有重复的文案出现
以项目为例,所有与项目相关的文案都放在project 对象内。
// 单一功能
<button @click="goBack"> 返回上一页 button>
// 复杂功能 - 需要对子组件emit的change事件做出响应
<xxx-page @change="handleXXXChange">xxx-page>
1.3、一个好的命名,应该是能让别人一眼就看出用途的,所以请根据你的目的进行命名,如果转化为英文后名字过长,可酌情使用简写
2、注释
对于注释,我的理解是注释在于而精不在于多,注释并不是越多越全就越好,因为写注释会耗费部分时间,且后续逻辑出现变化,还需要对注释进行维护更新,如果只更新了逻辑而忘记更新注释,那将是毁灭性的灾难,后面其他人看到这段驴头不对马嘴的代码和注释,一头雾水还要根据git记录跑来问你,这会耗费更多的时间。
2.1、对于逻辑较复杂的代码,首先应在复杂代码块初始位置,写出本段逻辑处理的目的,然后针对复杂点逐行写出逻辑处理原因 2.2、当写有注释的代码发生变化时,务必要检查对应的注释,并同步修改 2.3、对于代码行的注释使用双斜 // 即可,对于方法务必使用 /**/,并对出入参和出参做出注释因此对于一部分不太复杂的逻辑,完全可以通过优秀的变量或方法命名,让人在阅读时迅速理解这段代码的用途。当你自己在写这块代码时,都觉得业务难易理解或代码难以组织时,请务必加上注释
/**
* 检查项目名称是否重复
* @param name 项目名称
* @param customerId 客户主键
* @param id 项目主键(修改项目时需要传入该参数)
* @returns 返回true则代表重复
*/
public checkProjectName(name: string, customerId: number, id?: number): Promise<boolean> {}
3、变量声明
3.1、对于数组和对象或其他引用类型,后续不影响引用地址的情况下,允许使用const定义
3.2、非必要情况下,不要定义临时变量 3.3、定义对象时,请使用对象属性值的简写方式const job = 'FrontEnd'
// bad
const item = {
job: job
}
// good
const item = {
job
}
3.4、变量不要进行链式赋值,会污染全局变量
// bad
(function example() {
// let 关键字只适用于变量 a; 变量 b 和 c 变为全局变量
let a = b = c = 1
}())
console.log(a) // ReferenceError
console.log(b) // 1
console.log(c) // 1
// good
(function example() {
let a = 1
let b = a
let c = a
}())
console.log(a) // ReferenceError
console.log(b) // ReferenceError
console.log(c) // ReferenceError
3.5、// bad
import foo from 'foo'
// … some other imports … //
import { named1, named2 } from 'foo'
// good
import foo, { named1, named2 } from 'foo'
5、function
5.1、// bad
function test () {
const args = Array.prototype.slice.call(arguments)
return args.join('')
}
// good
function test (...args) {
return args.join('')
}
6、其他
6.1、// bad
if(xxx){
do something1;
} else {
do something2;
if(xxx) {
do something3;
} else {
do something4;
}
}
// good
if(xxx){
do something1;
return;
}
do something2;
if(xxx) {
do something3;
return;
}
do something4;
6.6、优先使用promise,若非绝对必要,禁止使用回调函数
6.7、使用async和await语法糖时,必须使用try catch
ts规范
1、访问修饰符
1.1、在声明变量或方法时,针对该方法的目的,设置访问权限
使用方式参考 ts 官方文档
1.2、 public selectedRows: Array<ProjectList> = [];
private queryForm: Partial<ProjectListQuery> = {};
public created(): void {
}
private clearSelection(): void {
}
1.3、对于vue的prop,或inject,请使用readonly修饰
2、类型声明
2.1、类型声明文件后缀名为.d.ts,统一放在项目src/resource下面
2.2、类型统一使用大驼峰命名
2.3、要求以每个对象和具体功能为基础,建立该对象的相关 *** 作的实体类,统一导出
以项目对象project为例,功能包含
- 列表页 ProjectList
- 分页查询条件检索 ProjectListQuery
- 新增、编辑 CreateProject,如果编辑只需要对少部分字段进行修改,则建立 UpdateProject
- 详情页展示 ProjectInfo
以上类型一般基于一个较为全面的基础类型,改造而来。ts提供了诸如使用Omit,Pick,Partial,Required关键字,对类型进行修改,从而获得一个新的类型。这样当字段发生变化时,只需使用vscode重构功能,对基础类型进行修改后,即可同步影响到所有相关的类型。
可根据实际情况,选择ProjectInfo或ProjectList作为基类,当都不满足条件时,可以选择声明ProjectBase类型抽取公共字段。
2.4、对于每个类型和属性声明,必须具有注释 2.5、对于数组的定义,使用泛型方式// good
const arr: number[] = [1, 2, 3];
// best
const arr: Array<number> = [1, 2, 3];
3、function
3.1、 public xxx(): void {
do something;
}
protected xxx(): boolean {
return true;
}
private xxx(): string {
return 'xxxxxx';
}
public xxx(): 其他支持的类型 {
return 其他支持的类型
}
4、其他
4.1、若非必要,禁止使用any类型
4.2、枚举必须具有注释,且后缀名必须为Enum
枚举对应的i18n翻译,一般以枚举名,去掉Enum后缀,然后以小驼峰命名,例如ProjectStatusEnum
,代表项目状态枚举类
/**
* 项目状态
*/
export enum ProjectStatusEnum {
/**
* 新建
*/
new = 1,
....
}
i18n文案为
projectStatus: {
new: '新建',
...
}
vue
1、模板文件
1.1 、组件模板应该只包含简单的表达式,复杂的表达式则应该重构为计算属性或方法。
// bad
<el-button size="small" @click="detailsVisible = false">关闭el-button>
// good
<el-button size="small" @click="close">关闭el-button>
// bad
<span>{{ totalMoney * 2 }}span>
// good
<span>{{ doubleMoney }}span>
public close ():void {
this.detailsVisible = false
}
public get doubleMoney(): number {
return this.doubleMoney * 2
}
2、命名问题
2.1 、组件命名采用短横线命名法
2.2 、emit 事件单词之间使用 - 分隔,禁止使用驼峰
2.3 、组件传参时,标签上需要对使用了驼峰命名的prop,使用短横线命名
假如 B组件接收一个totalMoney,A组件传参时如下
// good
<b :totalMoney="123">b>
// best
<b :total-money="123">b>
// error
<b totalMoney="123">b>
3、其他
3.1 、设置prop时,必须填写options
@Prop({ type: String, required: true })
public readonly msg!: string;
@Prop({ type: String, required: false, default:'' })
public readonly msg!: string;
3.2 、更多请参照 vue风格指南
css
1、命名
1.1、使用短横线进行class命名
2、其他
2.1、多页面都用到的公共样式,禁止复制粘贴,必须放在src/style/index.scss中
2.2、注释使用单行注释
注释内容第一个字符和最后一个字符都是一个空格字符,单独占一行,行与行之间相隔一行
/* Comment Text */
.jdc{}
/* Comment Text */
.jdc1{}
2.3、scss可复用属性尽量抽离为变量,易于统一维护
…未完待续
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)