前端开发规范

规范的目的是为了编写高质量的代码,让你的团队成员每天的心情都是愉悦的,大家在一起是快乐的。

引自《阿里规约》的开头片段:

----现代软件架构的复杂性需要协同开发完成,如何高效地协同呢?无规矩不成方圆,无规范难以协同,比如,制定交通法规表面上是要限制行车权,实际上是保障公众的人身安全,试想一下,如果没有限速,没有红绿灯,谁还敢上路行驶。对软件来说,适当的规范和标准绝不是消灭代码内容的创造性、优雅性,而是限制过度个性化,以一种普通认可的统一方式一起做事,提升协作效率,降低沟通成本。代码的字里行间流淌的是软件系统的血液,质量的提升是尽可能少踩坑,杜绝踩重复的坑,切实提升系统的稳定性,码出质量。

一、命名规范

注意: 项目名,文件名不能包含 /:?<>| 等特殊符号(windows系统不兼容)

1. 前端业务项目命名

  1. 全部采用小写方式, 并以中划线"-"分隔。
  2. 以对应的业务组名开头,如:“saas-”,“axcloud-”,“market-”,“tools-platform-”开头。
  3. 中间部分必须和后端同学,或者对应的master沟通好之后命名(怕命名重复,或命名不统一,前后端同一项目,命名不同)。
  4. 根据应用场景,以“-web”,“-h5”,“-pc”,“-admin”结尾。
    例如:saas-xxx-admin

2. 其他前端项目命名

  1. 全部采用小写方式, 并以中划线"-"分隔。
  2. 模版项目以”-template“结尾。
    例如:xxx-template

3. 目录命名

  1. 全部采用小驼峰格式 。
  2. 有复数结构时,要采用复数命名法,缩写不用复数。
    正例:scripts / styles / components / images / utils / layouts / demo-styles / demo-scripts / img / doc / api
    反例:script / style / demoScripts / demoStyles / imgs / docs / apis
  3. 【特殊】VUE项目中的components组件目录,使用大驼峰命名
    正例:HeadSearch / PageLoading
  4. 【特殊】VUE的项目中的除了components组件目录外的所有目录也使用小驼峰格式命名。
    正例:pageOne / shoppingCar / userManagement
    反例:ShopingCar / UserManagement

4. js、css、scss、HTML、PNG文件命名

全部采用小驼峰格式命名。

5 使用Vue或者React技术栈,组件Component命名

全部采用大驼峰格式命名。
例:MyComponent.vue

命名的严谨性

代码中的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式。
说明:正确的英文拼写和语法可以让阅读者更易于理解,避免歧义。
注意:即使纯拼音命名方式也要避免采用。
正例:henan / luoyang /rmb 等国际通用的名称,可视为英文。
反例:DaZhePromotion [打折] / getPingFenByName [评分] / int 某变量 = 3

杜绝完全不规范的缩写,避免望文不知义

需做到望文知义
反例:AbstractClass —> AbsClass,condition —> condi
此类随意缩写严重降低例代码的可阅读性。
如果太长,要用缩写,必须把原来的英文放在注释里。

二、HTML规范(Vue Template同样适用)

1. HTML类型

推荐使用HTML5的文档类型声明:
(建议使用text/html格式的HTML。避免使用XHTML。XHTML以及它的属性,比如application/xhtml + xml在浏览器中的应用支持与优化空间都十分有限)。

  • 规定字符编码
  • IE兼容模式
  • doctype大写

正例:

1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta charset="UTF-8" />
<title>Page Title</title>
</head>
<body>
<img src="images/company-logo.png" alt="Company">
</body>
</html>

2. 缩进

  1. 缩进使用2个空格(1个tab)
  2. 嵌套的节点应该缩进。

3. 分块注释

在每一个块状元素,列表元素和表格元素后,加上一对HTML注释。
注释格式:
<!– 英文 / 中文 start -->
<!– 英文 / 中文 end -->
正例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html>
<!-- 头部 start -->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta charset="UTF-8" />
<title>Page Title</title>
</head>
<!-- 头部 end -->
<!-- body start -->
<body>
<a href="#">
<!-- 图片会把a标签给撑开,所以不用设置a标签的大小 -->
<img src="images/company-logo.png" alt="Company">
</a>
</body>
<!-- body end -->
</html>

4. 语义化标签

HTML5中新增很多语义化标签,所以优先使用语义化标签,避免一个页面都是div或者p标签
正例:

1
2
<header></header>
<footer></footer>

反例:

1
2
3
<div>
<p></p>
</div>

5. 引号

  • 使用双引号(“”)
  • 不使用单引号(‘’)

6. 引入CSS, JS

根据HTML5规范, 通常在引入CSS和JS时不需要指明 type,因为 text/css和 text/javascript 分别是他们的默认值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- External CSS -->
<link rel="stylesheet" href="code_guide.css">

<!-- In-document CSS -->
<style>

</style>

<!-- External JS -->
<script src="code_guide.js"></script>

<!-- In-document JS -->
<script>
// ...
</script>

7. 属性顺序

属性名全小写,用中划线做分隔符

1
2
3
4
5
6
7
8
9
10
11
12
# 由prettier格式化
class
id
name
data-*
src, for, type, href, value , max-length, max, min, pattern
placeholder, title, alt
aria-*, role
required, readonly, disabled

class是为高可复用组件设计的,所以应处在第一位;
id 具体且应该尽量少使用,所以将它放在第二位。
1
2
3
4
5
<a class="..." id="..." data-modal="toggle" href="#">Example link</a>

<input class="form-control" type="text">

<img src="..." alt="...">

8. 减少标签数量

需要尽量避免多余的父节点;

1
2
3
4
5
6
7
<!-- 不建议这么做 -->
<span class="avatar">
<img src="...">
</span>

<!-- 建议这么做 -->
<img class="avatar" src="...">

9. 其他

  1. 标签必须要关闭
  2. p标签不允许嵌套div等标签
1
2
3
4
5
6
7
8
<!-- 例 -->
<p>
<div></div>
</p>
<!-- 部分浏览器会解析成 -->
<p></p>
<div></div>
<p></p>

三、CSS/SCSS规范

  • 缩进统一为2个空格
  • 不允许有空的规则出现;
  • 元素选择器用小写字母;
  • 样式的顺序通过prettier来修改;

CSS规范

1. 命名

  • 类名使用小写字母,以中划线分隔
  • id采用驼峰试命名
  • scss中的变量、函数、混合、placeholder采用驼峰式命名
    id和class的名称总是使用可以反应元素目的和用途的名称,或其他通用的名称,代替表象和晦涩难懂的名称
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* 不推荐: */
.fw-800 {
font-weight: 800;
}
.red {
color: red;
}

/* 推荐 */
.heavy {
font-weight: 800;
}
.important {
color: red;
}

2. 选择器

  1. css选择器中避免使用标签名
    从结构、表现、行为分离的原则来看,应该尽量避开css中出现的HTML标签,并且在css选择器中出现标签名会存在潜在的问题。
  2. 很多前端开发人员写选择器链的时候,不使用直接子选择器(注:直接子选择器和后代选择器的区别)。有时,这可能会导致疼痛的设计问题,并且有时候可能会很耗性能。然而,在任何情况下,这个是一个非常不好的做法。如果你不写很通用,需要匹配到DOM末端的选择器,你应该总是考虑直接子选择器。
1
2
3
4
5
6
7
8
9
/* 不推荐 */
.content .title {
font-size: 2rem;
}

/* 推荐 */
.content > .title {
font-size: 2rem;
}

3. 尽量使用缩写属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* 不推荐 */
.title {
border-top-style: none;
font-family: palatino, georgia, serif;
font-size: 100%;
line-height: 1.6;
padding-bottom: 2em;
padding-left: 2em;
padding-right: 2em;
padding-top: 2em;
}

/* 推荐 */
.title {
border-top: 0;
font: 100%/1.6 palatino, georgia, serif;
padding: 2em;
}

4. 每个选择器及属性独占一行

1
2
3
4
5
6
7
8
9
10
11
12
/* 不推荐 */
.title {
width: 100px;height: 50px; color: #fff; background: #00a0e9;
}

/* 推荐 */
.title {
width: 100px;
height: 50px;
color: #fff;
background: #00a0e9;
}

5. 省略0后面的单位

1
2
3
4
5
6
7
8
9
10
11
/* 不推荐 */
.title {
padding-bottom: 0px;
margin: 0em;
}

/* 推荐 */
.title {
padding-bottom: 0;
margin: 0;
}

6. 避免使用ID选择器及全局标签选择器,防止污染全局样式

1
2
3
4
5
6
7
8
9
10
11
/* 不推荐 */
#title {
padding-bottom: 0;
margin: 0;
}

/* 推荐 */
.title {
padding-bottom: 0;
margin: 0;
}

SCSS规范

1. 将公共的scss文件放置在style文件夹内

  1. 放置在项目的/src/styles内
  2. nuxt项目可以直接放到/styles内

2. 按以下顺序组织

  1. @import;
  2. 变量声明;
  3. 样式声明;
1
2
3
4
5
6
7
8
@import "styles/size.scss";

@default-text-color: #333;

.page {
width: 960px;
margin: 0 auto;
}

3. 避免嵌套层级过多

  1. 将嵌套深度限制在3级。对于超过4级的嵌套,给予重新评估,这可以避免出现过于祥实的CSS选择器;
  2. 避免大量的嵌套规则。当可读性受到影响时,将之打断。推荐避免出现多于20行的嵌套规则出现;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* 不推荐 */
.main {
.title {
.name {
color: #fff;
}
}
}

/* 推荐 */
.main-title {
.name {
color: #fff;
}
}

四、JavaScript规范

1. 命名

  1. 采用小写驼峰命名lowerCamelCase,代码中的命名均不能以 “_” 开头,也不能以 “_” 或者 “$” 结束;

反例:_name / name_ / name$;

  1. 方法名、参数名、成员变量、局部变量都统一用lowerCamelCase风格,必须遵从驼峰形式;

正例:localValue / getHttpMessage() / inputUserId

  1. *** 其中method方法命名必须是 “动词” 或者 “动词 + 名词” 的形式 ***

正例:saveShopCarData / openShopCarInfoDialog
反例:save / open / show / go

  1. *** 特此说,增删改查,详情统一使用如下5个单词,不得使用其他 *** (目的是为了统一各个端)

add / delete / update / get / detail

  1. 常量命名全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌弃名字长。

正例:MAX_STOCK_COUNT
反例:MAX_COUNTs

附:函数方法常用的动词
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
handle 处理
toggle 切换
reset 重置
init 初始化
get 获取 / set 设置
add 增加 / remove 删除
create 创建 / destory 移除
start 开始 / stop 停止
start 开始 / finish 完成
begin 开始 / end 结束
open 打开 / close 关闭
read 读取 / write 写入
load 载入 / save 保存
create 创建 / destroy 销毁
backup 备份 / restore 恢复
import 导入 / export 导出
split 分割 / merge 合并
inject 注入 / extract 提取
attach 附着 / detach 脱离
bind 绑定 / separate 分离
view 查看 / browse 浏览
edit 编辑 / modify 修改
select 选取 / mark 标记
copy 复制 / paste 粘贴
undo 撤销 / redo 重做
insert 插入 / delete 移除
add 加入 / append 添加
clean 清理 / clear 清除
index 索引 / sort 排序
find 查找 / search 搜索
increase 增加 / decrease 减少
play 播放 / pause 暂停
launch 启动 / run 运行
compile 编译 / execute 执行
debug 调试 / trace 跟踪
observe 观察 / listen 监听
build 构建 / publish 发布
input 输入 / output 输出
encode 编码 / decode 解码
encrypt 加密 / decrypt 解密
compress 压缩 / decompress 解压缩
pack 打包 / unpack 解包
parse 解析 / emit 生成 / build 构建
generate 生成 / emit 发射
connect 连接 / disconnect 断开
send 发送 / receive 接收
download 下载 / upload 上传
refresh 刷新 / synchronize 同步
update 更新 / revert 复原
lock 锁定 / unlock 解锁
check out 签出 / check in 签入
submit 提交 / commit 交付
push 推 / pull 拉
expand 展开 / collapse 折叠
enter 进入 / exit 退出
abort 放弃 / quit 离开
obsolete 废弃 / depreciate 废旧
collect 收集 / aggregate 聚集
shim 衬垫 / sham 伪装
pick 拿取 / seek 寻找
translate 平移/翻译 / rotate 旋转
zoom 变焦 / scale 缩放
skew 歪曲 / shear 剪切

涉及返回逻辑值的函数可以使用is,can,has,contains等表示逻辑的词语代替动词
附2:一些其他变量命名常用规范(仅供参考)
1
2
3
4
5
6
7
8
* s:表示字符串。例如:sName,sHtml;
* n:表示数字。例如:nPage,nTotal;
* b:表示逻辑。例如:bChecked,bHasLogin;
* a:表示数组。例如:aList,aGroup;
* r:表示正则表达式。例如:rDomain,rEmail;
* f:表示函数。例如:fGetHtml,fInit;
* o:表示以上未涉及到的其他对象,例如:oButton,oDate;
* g:表示全局变量,例如:gUserName,gLoginTime;
附3:按照前缀区分(仅供参考)
1
2
3
4
5
6
7
8
* $:表示Jquery对象。例如:$Content,$Module;
一种比较广泛的Jquery对象变量命名规范。
* j:表示Jquery对象。例如:jContent, jModule;
另一种Jquery对象变量命名方式。
* fn:表示函数。例如:fnGetName,fnSetAge;
和上面函数的前缀略有不同,改用fn来代替,个人认为fn能够更好的区分普通变量和函数变量。
* dom:表示Dom对象,例如:domForm,domInput;
项目中很多地方会用到原生的Dom方法及属性,可以根据团队需要适当修改。

2. 代码格式

  1. 使用2个空格进行缩进;
1
2
3
4
5
if (x < y) {
x += 10;
} else {
x += 1;
}
  1. 不同逻辑、不同语义,不同业务的代码之间插入一个空行分隔开来,以提升可读性;

说明:任何情形,没有必要插入多个空行进行隔开。

  1. 字符串统一使用单引号('),而不使用双引号(")。这在创建HTML字符串非常有好处,单引号的处理速度也比双引号快;
1
2
3
4
5
6
7
// 正例
let str = 'foo';
let testDiv = '<div id="test"></div>';

// 反例
let str = "foo";
let testDiv = "<div id='test'></div>";

4. 对象声明

  1. 使用字面值创建对象;
1
2
3
4
5
// 正例
let user = {};

// 反例
let user = new Object();
  1. 使用字面量来代替对象构造器;
1
2
3
4
5
6
7
8
9
10
11
12
// 正例
let user = {
age: 0,
name: 1,
city: 2
};

// 反例
let user = new Object();
user.age = 0;
user.name = 1;
user.city = 2;

5. 使用ES6,7

必须优先使用ES6,7中新增的语法糖和函数。这将简化你的程序,并让你的代码更加灵活和可复用。

必须强制使用ES6,ES7的新语法,比如箭头函数,await/async,解构,let,for…of等等。

6. 括号

下列关键字后必须有大括号(即使代码块的内容只有一行):

if, else, for, while, do, switch, try, catch, finally, with。

1
2
3
4
5
6
7
// 正例
if (condition) {
doSomething();
}

// 反例
if (condition) doSomething();

7. undefined 判断

  1. 永远不要直接使用undefined进行变量判断;
  2. 使用typeof和字符串’undefined’对变量进行判断;
1
2
3
4
5
6
7
8
9
// 正例
if (typeof person === 'undefined') {
// do...
}

// 反例
if (person === undefined) {
// do...
}

8. 条件判断和循环最多三层

条件判断能使用三元运算符和逻辑运算符解决的,就不要使用条件判断,但是谨记不要写太长的三元运算符。

如果超过3层,请抽成函数,并写清楚注释。

9. this 的转换命名

对上下文 this 的引用只能使用’self’来命名。

10. 慎用 console.log

因 console.log 的大量使用会有性能问题,所以在非webpack项目中谨慎使用log功能。

其他

1)缩进 2个空格

2)属性末尾加分号

3) 空格 在对象,数组括号与文字之间加空格

通过配置prettier实现

4)注释

单行:双斜线后,必须跟一个空格;缩进与下一行代码保持一致;可位于一个代码行的末尾,与代码间隔一个空格。

1
2
3
4
5
6
7
if (condition) {
// if you made it here, then all security checks passed
allowed();
}

var zhangsan = 'zhangsan'; // one space after code

多行:最少三行, '*'后跟一个空格

1
2
3
4
/*
* one space after '*'
*/
var x = 1;

方法注释

1
2
3
4
5
6
7
8
9
10
11
/**
* @description 我是一个方法
* @param {string} p1 参数1的说明
* @param {string} p2 参数2的说明,比较长
* 那就换行了.
* @param {number=} p3 参数3的说明(可选)
* @return {Object} 返回值描述
*/
function fun(p1, p2, p3) {
return {}
}

5) 变量命名

  • 标准变量采用驼峰式命名
  • 'ID’在变量名中全大写
  • 'URL’在变量名中全大写
  • 'Android’在变量名中大写第一个字母
  • 'iOS’在变量名中小写第一个,大写后两个字母
  • 常量全大写,用下划线连接
  • 构造函数,大写第一个字母

6)函数

无论是函数声明还是函数表达式,'(‘前不要空格,但’{'前一定要有空格;

函数调用括号前不需要空格;

立即执行函数外必须包一层括号;

不要给inline function命名;

参数之间用’, '分隔,注意逗号后有一个空格。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// no space before '(', but one space before'{'
var doSomething = function(item) {
// do something
};

function doSomething(item) {
// do something
}

// not good
doSomething (item);

// good
doSomething(item);

// requires parentheses around immediately invoked function expressions
(function() {
return 1;
})();

// not good
[1, 2].forEach(function x() {
...
});

// good
[1, 2].forEach(function() {
...
});

// not good
var a = [1, 2, function a() {
...
}];

// good
var a = [1, 2, function() {
...
}];

// use ', ' between function parameters
var doSomething = function(a, b, c) {
// do something
};

7) 数组、对象

对象属性名不需要加引号;

对象以缩进的形式书写,不要写在一行;

数组、对象最后不要有逗号。
可通过prettier 配置实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// not good
var a = {
'b': 1
};

var a = {b: 1};

var a = {
b: 1,
c: 2,
};

// good
var a = {
b: 1,
c: 2
};

8) 括号

下列关键字后必须有大括号(即使代码块的内容只有一行):if, else,for, while, do, switch, try, catch, finally, with。

1
2
3
4
5
6
7
8
9
// not good
if (condition)
doSomething();

// good
if (condition) {
doSomething();
}

其他

  • 不要混用tab和space;
  • 不要在一处使用多个tab或space;
  • 换行符统一用’LF’;
  • 对上下文this的引用只能使用’_this’, ‘that’, 'self’其中一个来命名;
  • 行尾不要有空白字符;
  • switch的falling through和no default的情况一定要有注释特别说明;
  • 不允许有空的代码块。

五、VUE规范

vue 项目规范以Vue官网规范( https://cn.vuejs.org/v2/style-guide )中的A规范为基础,在其上班进行项目开发,故所以代码均遵守该规范。

请仔仔细细阅读Vue官方规范,切记,此为第一步。

1. 组件规范

  1. 组件名为多个单词;

组件名应该始终是多个单词组成(大于等于2),且命名规范为KebabCase格式。
这样做可以避免跟现有的以及未来的HTML元素冲突,因为所以的HTML元素名称都是单个单词的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 正例
export default {
name: 'TodoItem',
// ...
}

// 反例
export default {
name: 'Todo',
// ...
}
export default {
name: 'todo-item',
// ...
}
  1. 组件文件名为大驼峰格式;
1
2
3
4
5
6
7
8
# 正例
components /
|- MyComponent.vue

# 反例
components /
|- myComponent.vue
|- my-component.vue
  1. 基础组件文件名为base开头,使用完整单词,而不是缩写;
1
2
3
4
5
6
7
8
9
10
11
# 正例
components /
|- base-button.vue
|- base-table.vue
|- base-icon.vue

# 反例
components /
|- MyButton.vue
|- VueTable.vue
|- Icon.vue
  1. 和父组件紧密耦合的子组件应该以父组件名作为前缀命名;
1
2
3
4
5
6
7
8
9
10
11
12
13
# 正例
components /
|- todo-list.vue
|- todo-list-item.vue
|- todo-list-item-button.vue
|- user-profile-options.vue # (完整单词)

# 反例
components /
|- TodoList.vue
|- TodoItem.vue
|- TodoButton.vue
|- UProfOpts.vue # (使用来缩写)
  1. 在template 模版中使用组件,应使用PascalCase模式,并且使用自闭组件;
1
2
3
4
5
6
7
8
<!-- 正例 -->
<!-- 在单文件组件、字符串模版和JSX中 -->
<MyComponent />
<Row><table :column="data" /></Row>

<!-- 反例 -->
<my-component />
<row><table :column="data" /></row>
  1. 组件的data必须是一个函数;

当在组件中使用data属性的时候(除了new Vue外的任何地方),它的值必须是返回一个对象的函数。
因为如果直接是一个对象的化,子组件之间的属性值会相互影响。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 正例
export default {
data () {
return {
name: 'jack',
}
}
// ...
}

// 反例
export default {
data: {
name: 'jack',
}
// ...
}
  1. Prop 定义应该尽量详细
  1. 必须使用camelCase驼峰命名;
  2. 必须指定类型;
  3. 必须加上注释,表面其含义;
  4. 必须加上required 或者 default,两者二选其一;
  5. 如果有业务需要,必须加上validator 验证;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 正例
export default {
props: {
// 组件状态,用于控制组件的颜色
status: {
type: String,
required: true,
validator: function (value) {
return [
'succ',
'info',
'error',
].indexOf(vaule) !== -1
}
},
// 用户级别,用于显示皇冠个数
userLevel: {
type: String,
required: true
}
}
}
  1. 为组件样式设置作用域
1
2
3
4
5
6
7
8
9
10
<template>
<button class="btn btn-close">X</button>
</template>

<!-- 正例:使用‘scoped’特性 -->
<style scoped>
.btn-close {
color: red
}
</style>
  1. 如果特性元素较多时,应该主动换行。
1
2
3
4
5
6
7
8
<!-- 正例 -->
<MyComponent
foo="a"
bar="b"
baz="c"
/>
<!-- 反例 -->
<MyComponent foo="a" bar="b" baz="c" />

2. 模版中使用简单的表达式

组件模版应该只包含简单的表达式,复杂的表达式则应该重构为计算属性或方法。

复杂的表达式会让你的模版变得不那么声明式,我们应该尽量描述应该出现的是什么,而非如何计算那个值,而且计算属性和方法使得代码可以重用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!-- 正例 -->
<template>
<p>{{ normalizedFullName }}</p>
</template>

<script>
export default {
// 复杂表达式已经移入一个计算属性
computed: {
normalizedFullName () {
return this.fullName.split(' ').map((word) => word[0].toUpperCase() + word.slice(1)).join(' ');
}
}
}
</script>

<!-- 反例 -->
<template>
<p>{{ fullName.split(' ').map((word) => word[0].toUpperCase() + word.slice(1)).join(' ') }}</p>
</template>

3. 指令都使用缩写形式

指令推荐都使用缩写形式

  • 用":“表示"v-bind”
  • 用"@“表示"v-on”
  • 用"#“表示"v-slot”
1
2
3
4
5
6
7
8
9
10
11
<!-- 正例 -->
<input
@input="onInput"
@focus="onFocus"
/>

<!-- 反例 -->
<input
v-on:input="onInput"
@focus="onFocus"
/>

4. 标签顺序必须保持一致

单文件组件应该总是让标签顺序保持为

1
2
3
<template></template>
<script></script>
<style></style>

5. 必须为 v-for 设置健值 key

6. v-show 与 v-if 选择

如果运行时,需要非常频繁地切换,使用v-show;
如果运行时,条件很少改变,使用 v-if;

7. 避免 v-if 和 v-for 用在一起

永远不要把 v-if 和 v-for 同时用在同一个元素上。

一般我们在两种常见的情况下会倾向于这样做:

  • 为了过滤一个列表中的项目 (比如 v-for=“user in users” v-if=“user.isActive”)。在这种情形下,请将 users 替换为一个计算属性 (比如 activeUsers),让其返回过滤后的列表。
  • 为了避免渲染本应该被隐藏的列表 (比如 v-for=“user in users” v-if=“shouldShowUsers”)。这种情形下,请将 v-if 移动至容器元素上 (比如 ul、ol)。

8. script标签内部结构顺序

components > props > data > computed > watch > filter > 钩子函数(钩子函数按其执行顺序) > methods

Vue Router 规范

1. 页面跳转数据传递使用路由参数

页面跳转,例如 A 页面跳转到 B 页面,需要将 A 页面的数据传递到 B 页面,推荐使用路由参数进行传参,而不是将需要传递的数据保存 vuex,然后在 B 页面取出 vuex 的数据,因为如果在 B 页面刷新会导致 vuex 数据丢失,导致 B 页面无法正常显示数据。

1
2
let id = '123';
this.$router.push({ name: 'userCenter', query: { id: id } });

2. 使用路由懒加载(延迟加载)机制

1
2
3
4
5
6
7
8
{
path: '/uploadAttachment',
name: 'uploadAttachment',
meta: {
title: '上传组件'
},
component: () => import('@/views/uploadAttachment.vue')
}

3. router 中的命名规范

  1. path、chilrenPoints 命名规范采用 kebab-case 命名规范(尽量vue文件的目录结构保持一致,因为目录、文件名都是 kebab-case,这样很方便找到对应的文件)
  2. name 命名规范采用 kebabCase 命名规范,且和 component 组件名保持一致!(因为要保持 keep-alive 特性,keep-alive 按照 component 的 name 进行缓存,所以两者必须高度保持一致)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 动态加载
export const reload = [
{
path: '/reload',
name: 'reload',
component: Main,
meta: {
title: '动态加载',
icon: 'icon iconfont'
},
children: {
path: '/reload/smart-reload-list',
name: 'smartReloadList',
component: Main,
meta: {
title: '动态加载',
icon: 'icon iconfont'
},
component: () => import('@/views/reload/smart-reload-list.vue')
}
}
]

Vue 项目目录规范

1. 基础

vue项目中的所有命名一定要和后端命名统一;

比如权限:后端privilege,前端物理router,store,api等都必须使用privielege单词

2. 使用 vue-cli 脚手架

使用 vue-cli4 版本的脚手架来初始化项目。

3. 目录说明

目录名按照上面的命名规范,其中 components 组件用大写驼峰,其余除 components 组件目录外的所以目录均使用 kebab-case 命名。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
- mock    # mock服务,后期会添加mockjs,加强mock的能力
- publish # 公共目录,可以放一些需要放跟目录下文件可以直接拷贝到这边
- src # 源代码目录
- api # 公共的api接口文件夹,放组件里的接口或其他公共地方需要使用的接口,即非页面级的接口,方便统一管理
- assets # 静态资源目录
- components # 公共组件目录,非页面级组件目录
- filters # vue的filters组件目录
- layout # 项目的layout放置目录
- index.js # 默认的layout 可以给多个layout使用,前提需在router/index.js上配置
- router # 路由目录
- index.js # 当有新的layout出现时,需在此文件添加你的layout,并指定layout
- routes.js # 会自动去找views目录下的routes.js文件,并通过layout参数区分不同的routes
- styles # 公共样式目录
- utils # 公共工具目录
- views # 项目页面
- admin # layout为默认的layout,命名为admin的页面目录,访问路径为:/admin/xxx/xxx
- home # layout 为admin的某一导航栏内容,包括改导航栏的一二级导航, 访问路径为:/admin/home/xxx
- login # 页面的登录页面,后期单点登录项目上线后,会修改
- test # 供给大家参考的目录,包括两个列表页面,后期会添加更多页面供大家拷贝,查看页面路径:/test
- App.vue # vue的入口文件
- main.js # 项目的入口文件
- defaultSettings.js # 公共的配置文件
- registerServiceWorker.js # pwa文件

4. views 页面结构说明

1
2
3
4
5
6
7
8
views/xxx # layout名字一样的集合,admin为admin的集合,test为test的集合,命名是在views下面的route.js里
views/test/xxx # test集合下的某一级导航,里面包含各种二级页面
views/test/list # test集合下的list测试列表
- components # 该级下的组件文件夹
- api.js # 该级下的api集合
- index.vue,detail.vue # 该级下的页面,也可以建一个目录放置
- mock.js # 该级下的本地mock数据,目前只是简单的mock,后期会添加mockjs加强处理mock数据
- routes.js # 该级下的路由,使用参考/views/test/list/routes.js

5. 注释说明

整理必须加注释的地方

  • 公共组件使用说明
  • api目录的接口js文件必须加注释
  • store 中的 state,mutation,action 等必须加注释
  • vue 文件中的template 必须加注释,若文件较大加start,end注释
  • vue 文件的methods,每个method必须加注释
  • vue 文件的data,非常常见的单词要加注释

6. 其他

  1. 尽量不要手动操作 DOM

因使用vue框架,所以在项目开发中,尽量使用 vue 的数据驱动更新 DOM,尽量(不到万不得已)不要手动操作 DOM,包括:增删改 DOM 的元素,以及更改样式,添加事件等。

  1. 删除无用代码

因使用了 git 代码管理工具,对于无用代码必须及时删除,例如:一些调用的 console 语句、无用的弃用功能代码。

参考文档

  1. js命名规范
  2. 前端开发规范:命名规范、html规范、css规范、js规范