前端常见代码规范
前言
本文档旨在规范前端编码规范,力求达到任何人阅读他人代码都能快速理解并着手开发,其他未总结到的编码格式规范应严格按照ESLint格式要求编写即可。
css规范
本文档的目标是规范组内代码风格,尽可能的使 同事们的 CSS 代码风格保持一致,容易被理解和被维护。 虽然本文档是针对 CSS 设计的,但是在使用各种 CSS 的预编译器(如 less、sass、stylus 等)时,适用的部分也应尽量遵循本文档的约定。
空格、缩进、属性简写
使用 2 个空格做为一个缩进层级,不允许使用 4 个空格 或 tab 字符。 选择器 与 {
之间必须包含空格。 属性名 与之后的 :
之间不允许包含空格, :
与 属性值 之间必须包含空格。 列表型属性值 书写在单行时, 后必须跟一个空格。 属性能简写时,必须简写,方便阅读和维护。 属性值为 0 时,建议不带单位,若带单位,须保持单个项目整体统一! 属性定义必须另起一行。 示例:
/* good */
.selector {
margin: 5px 10px;
padding: 0 10px 5px 10px;
font-family: Arial, sans-serif;
}
选择器
当一个 rule 包含多个 selector 时,每个选择器声明必须独占一行。 示例:
/* good */
.post,
.page,
.comment {
line-height: 1.5;
}
/* bad */
.post, .page, .comment {
line-height: 1.5;
}
/* 建议 >、+、~ 选择器的两边各保留一个空格。若不保留空格,须保持单个项目整体统一!
示例:*/
/* good */
main > nav {
padding: 10px;
}
label + input {
margin-left: 5px;
}
input:checked ~ button {
background-color: #69C;
}
/* 属性选择器中的值必须用双引号包围。
示例:*/
/* good */
article[character="juliet"] {
voice-family: "Vivien Leigh", victoria, female;
}
/* bad */
article[character='juliet'] {
voice-family: "Vivien Leigh", victoria, female;
}
清除浮动
当元素需要撑起高度以包含内部的浮动元素时,通过对父级的伪类设置 clear 进行 clearfix。 示例:
.clearfix::after {
content: "";
display: block;
clear: both;
}
.clearfix{
*zoom: 1;
}
颜色
RGB 颜色值必须使用十六进制记号形式 #rrggbb
。不允许使用 rgb() ,带有 alpha 的颜色信息可以使用 rgba() 。使用 rgba() 时每个逗号后必须保留一个空格。 示例:
/* good */
.success {
box-shadow: 0 0 2px rgba(0, 128, 0, .3);
border-color: #008000;
}
/* bad */
.success {
box-shadow: 0 0 2px rgba(0,128,0,.3);
border-color: rgb(0, 128, 0);
}
/*
颜色值不允许使用命名色值。
颜色值中的英文字符采用小写。如不用小写也需要保证同一项目内保持大小写一致。
示例:
*/
/* good */
.success {
background-color: #aaccaa;
color: #90ee90;
}
/* good */
.success {
background-color: #AACCAA;
color: #90EE90;
}
/* bad */
.success {
background-color: #ACA;
color: #90ee90;
}
过渡与动画
尽可能在浏览器能高效实现的属性上添加过渡和动画。能使用 transform
实现的效果绝不使用 transition
解释: 见本文,在可能的情况下应选择这样四种变换:
transform: translate(npx, npx);
transform: scale(n);
transform: rotate(ndeg);
opacity: 0.1;
/*
典型的,可以使用 translate 来代替 left 作为动画属性。示例:
*/
/* good */
.box {
transition: transform 1s;
}
.box:hover {
transform: translate(20px); /* move right for 20px */
}
/* bad */
.box {
left: 0;
transition: left 1s;
}
.box:hover {
left: 20px; /* move right for 20px */
}
JS 规范
本文档的目标是规范组内代码风格,尽可能的使 同事们的 JS 代码风格保持一致,容易被理解和被维护。
代码风格
- 使用2个空格进行缩进;
- 除需要转义的情况外,字符串统一使用单引号;
- 不要定义未使用的变量;
- 关键字后面加空格;
- 函数声明时括号与函数名间加空格;
- 无分号;
- 行首不要以 ( , [ , or ` 开头,这是省略分号时唯一会造成问题的地方;
- 等等……
解释:
-
本组代码风格应严格按照 JavaScript Standard Style 规则执行,具体细则参考 Standard 细则。
-
就目前而言,组内大部分使用 vue-cli 搭建的项目都已经集成好了 Standard 校验,具体配置可以参考根目录中的 .eslintrc.js文件,同时不排除未集成 Standard 校验的项目,此时应该按照 安装教程 并集成到自己的 IDE 中。
-
当项目中存在第三方库有大量代码无法通过格式校验时,可采用以下方法排除此类文件:
-
可以在
package.json
里添加standard.ignore
属性来配置:"standard": { "ignore": [ "**/out/", "/lib/select2/", "/lib/ckeditor/", "tmp.js" ] }
-
JavaScript Standard 代码规范底层使用的是 ESLint。所以如果需要隐藏某些警告,使用
/* eslint-disable */
即可
-
命名规则
基本原则:全英文命名,且命名规则应遵循基本的见名思意原则
见名思意 原则
在兼顾长度和可读性的情况下应尽可能准确的表达出其作用
- 变量名 和 函数名 使用小驼峰命名,即首字母小写,每个有意义的单词首字母大写
- 常量 使用 全部字母大写,单词间下划线分隔 的命名方式
-
boolean
类型的变量使用is
或has
开头
示例:
var loadingModules = {}
const HTML_ENTITY = {}
function stringFormat (source) {}
var isReady = false
var hasMoreCommands = false
注释
- 单行注释,
//
后跟一个空格;若另起一行,缩进与下一行被注释说明的代码一致 - 多行注释使用
/** **/
的方式
示例:
// 单行注释
/**
* 这是一个多行注释
* 多行注释的第二行
*/
- 方法/函数注释,应对方法功能和注意事项做简要描述,且注明所需参数的类型和说明
- 对 Object 中各项的描述, 必须使用
@param
标识。
示例:
/**
* 函数描述
*
* @param {string} p1 参数1的说明
* @param {string} p2 参数2的说明,比较长
* 那就换行了.
* @param {number=} p3 参数3的说明(可选)
* @return {Object} 返回值描述
*/
function foo(p1, p2, p3) {
var p3 = p3 || 10;
return {
p1: p1,
p2: p2,
p3: p3
}
}
/**
* 函数描述
*
* @param {Object} option 参数描述
* @param {string} option.url option项描述
* @param {string=} option.method option项描述,可选参数
*/
function foo(option) {
// TODO
}
var
、let
、const
- 在块级作用域中,使用
let
代替var
使用 - 在无特殊要求的
for
循环中,强制要求使用let
定义索引 - 在定义常量时,使用
const
类型转换
- 转换成
string
时,使用+ ''
- 转换成
number
时,通常使用+
或者- 0
-
string
转换成number
,要转换的字符串结尾包含非数字并期望忽略时,使用parseInt
- 使用
parseInt
时,必须指定进制 - 转换成
boolean
时,使用!!
-
number
去除小数点,使用Math.floor
/Math.round
/Math.ceil
,不使用parseInt
示例:
// good
num + ''
// bad
new String(num)
num.toString()
String(num)
_______________________
// good
+str;
str - 0
// bad
Number(str)
________________________
var width = '200px'
parseInt(width, 10)
________________________
// good
parseInt(str, 10)
// bad
parseInt(str)
________________________
var num = 3.14
!!num
________________________
// good
var num = 3.14
Math.ceil(num)
// bad
var num = 3.14
parseInt(num, 10)
对象
- 使用对象字面量
{}
创建新Object
- 对象创建时,如果一个对象的所有
属性
均可以不添加引号,建议所有属性
不添加引号 - 对象创建时,如果任何一个
属性
需要添加引号,则所有属性
建议添加'
-
属性
访问时,尽量使用.
-
for in
遍历对象时, 使用hasOwnProperty
过滤掉原型中的属性
示例:
// good
var obj = {}
// bad
var obj = new Object()
________________________
var info = {
name: 'someone',
age: 28
}
________________________
info.age
info['more-info']
________________________
var newInfo = {}
for (var key in info) {
if (info.hasOwnProperty(key)) {
newInfo[key] = info[key]
}
}
数组
- 使用数组字面量
[]
创建新数组,除非想要创建的是指定长度的数组 - 遍历数组不使用
for in
示例:
// good
var arr = []
// bad
var arr = new Array()
________________________
var arr = ['a', 'b', 'c'];
// 这里仅作演示, 实际中应使用 Object 类型
arr.other = 'other things'
// 正确的遍历方式
for (let i = 0, len = arr.length; i < len; i++) {
console.log(i)
}
// 错误的遍历方式
for (var i in arr) {
console.log(i)
}
Less 规范
本文档的目标是规范组内代码风格,尽可能的使 同事们的 Less 代码风格保持一致,容易被理解和被维护。Less 代码的基本规范和原则与Css规范保持一致。
代码组织
- 代码必须(MUST)按如下形式按顺序组织:
@import
- 变量声明
- 样式声明
示例:
// ✓
@import "est/all.less";
@default-text-color: #333;
.page {
width: 960px;
margin: 0 auto;
}
变量
- Less 的变量值总是以同一作用域下最后一个同名变量为准,务必注意后面的设定会覆盖所有之前的设定。
- 变量命名必须采用
@foo-bar
形式,不得使用@fooBar
形式。 - 变量命名不得使用
@font-14
形式,此种命名方式与直接书写font-size: 14px;
无异,而应该使用@font-size-normal
这种形式。
示例:
// ✗
@sidebarWidth: 200px;
@width:800px;
// ✓
@sidebar-width: 200px;
@width: 800px;
文件导入
- 使用
@import (reference)
导入less
文件,避免导入的less
文件代码重复打包到最终的css
文件中
解释:
原理参见 Less导入选项reference关键词 或自行google
示例:
@import (reference) "base.less"
Vue 规范
组件名
命名须遵循以下原则:
有意义的名词、简短、具有可读性,避免与 HTML 标签冲突,结构清晰。 以大写开头,采用大驼峰的命名方式。
组件文件夹命名主要以功能模块代表命名,采用中划线格式命名,达到看到中划线文件夹就知晓是组件效果。例如:article-item
。同时还需要注意:必须符合自定义元素规范。
示例:
// 反例
export default {
name: 'articleItem'
}
// 正例
export default {
name: 'ArticleItem'
}
Prop
定义 Prop 的时候应该始终以驼峰格式(camelCase)命名,且定义的时候应该尽量详细的指定其类型,默认值以及验证。
示例:
// 反例
props: ['attrM', 'attrA', 'attrZ']
// 正例
props: {
attrM: Number,
attrA: {
type: String,
required: true
},
attrZ: {
type: Object,
// 数组/对象的默认值应该由一个工厂函数返回
default: function ( ) {
return {
msg: '成就你我'
}
}
},
attrE: {
type: String,
validator: function (v) {
return !(['success', 'fail'].indexOf(v) === -1)
}
}
}
v-for
在执行 v-for
遍历的时候,总是应该带上 key 值使更新 DOM 时渲染效率更高。注意:v-for与v-if不能同时使用。
示例:
// 反例
<ul>
<li v-for="item in list">
{{ item.title }}
</li>
</ul>
// 正例
<ul>
<li v-for="item in list" :key="item.id">
{{ item.title }}
</li>
</ul>
v-if / v-else-if / v-else
若同一组 v-if
逻辑控制中的元素逻辑相同,Vue 为了更高效的元素切换,会复用相同的部分,例如: value 。为了避免复用带来的不合理效果,建议在同种元素上加上 key 做标识。
示例:
// 反例
<div v-if="hasData">
<span>{{ mazeyData }}</span>
</div>
<div v-else>
<span>无数据</span>
</div>
// 正例
<div v-if="hasData" key="mazey-data">
<span>{{ mazeyData }}</span>
</div>
<div v-else key="mazey-none">
<span>无数据</span>
</div>
指令缩写
为了统一规范始终使用指令缩写,使用 v-bind
, v-on
并没有什么不好,这里仅为了统一规范。
示例:
<input :value="mazeyUser" @click="verifyUser">
样式
为了避免样式冲突,整个项目建议全都使用 scoped 特性,若遇到使用动态生成 DOM 节点无法赋上 scopeId 的而无法修改样式的情况,应另行新建 reset 样式表全局引入,做单独的样式重置,
总结
本文档旨在规范前端编码规范,力求达到任何人阅读他人代码都能快速理解并着手开发,其他未总结到的编码格式还请补充指正。