前言
团队中的每一个人,对规范的理解是不统一的,任何团队开发中都需要规范,有统一的代码规范,肯定会事半功倍,方便维护。做了如下总结,参考来自腾讯 alloyteam团队 的代码规范。
目录、文件
项目命名
全部采用小写方式, 以下划线分隔。
例:my_project_name
目录命名
参照项目命名规则;
有复数结构时,要采用复数命名法。
例:scripts
, styles
, images
, data_models
JS文件命名
参照项目命名规则。
例:account_model.js
CSS, SCSS文件命名
参照项目命名规则。
例:retina_sprites.scss
HTML文件命名
参照项目命名规则。
例:error_report.html
VUE 组件命名
组件名首字母大写驼峰,应该由多单词组成,除了一些内置组件,如果是单个单词,加上标识 V
例:ToDoItem.vue
、VTable.vue
、VDetail.vue
补充
alloyteam团队
规范 项目命名推荐用下划线分隔,但在url中,使用连字符有一定的优势,因为像google这样的搜索引擎是会把连字符的单词断开,都作为关键词,而如果是下划线的话,则会把整体作为关键词(百度是两种情况都一视同仁),所以如果有SEO的需要,那建议url里的项目名称使用连字符。例:my-project-name
HTML
缩进使用soft tab(4个空格);
嵌套的节点应该缩进;
在属性上,使用双引号,不要使用单引号;
属性名全小写,用中划线做分隔符;
不要在自动闭合标签结尾处使用斜线(HTML5 规范 指出他们是可选的);
不要忽略可选的关闭标签,例:
</li>
和</body>
;在页面开头使用这个简单地doctype来启用标准模式,使其在每个浏览器中尽可能一致的展现;虽然doctype不区分大小写,但是按照惯例,doctype大写;
lang 属性,根据HTML5规范:应在html标签上加上lang属性。这会给语音工具和翻译工具帮助,告诉它们应当怎么去发音和翻译;
字符编码,通过声明一个明确的字符编码,让浏览器轻松、快速的确定适合网页内容的渲染方式,通常指定为'utf-8';
IE兼容模式,用
<meta>
标签可以指定页面应该用什么版本的IE来渲染;引入CSS, JS, 根据HTML5规范, 通常在引入CSS和JS时不需要指明 type,因为 text/css 和 text/javascript 分别是他们的默认值;
例:
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="stylesheet" href="test.css">
<script src="test.js"></script>
<title>Page title</title>
</head>
<body>
<img src="images/company_logo.png" alt="Company">
<h1 class="hello-world">Hello, world!</h1>
</body>
</html>
标签属性顺序
- class
- id
- name
- data-*
- src, for, type, href, value , max-length, max, min, pattern
- placeholder, title, alt
- aria-*, role
- required, readonly, disabled
class是为高可复用组件设计的,所以应处在第一位;
id更加具体且应该尽量少使用,所以将它放在第二位。
例:
<a class="..." id="..." data-modal="toggle" href="#">Example link</a>
<input class="form-control" type="text">
<img src="..." alt="...">
标签 boolean属性
boolean属性指不需要声明取值的属性,XHTML需要每个属性声明取值,但是HTML5并不需要
例:
<input type="text" disabled>
<input type="checkbox" value="1" checked>
<select>
<option value="1" selected>1</option>
</select>
JS生成标签
在JS文件中生成标签让内容变得更难查找,更难编辑,性能更差。应该尽量避免这种情况的出现。
减少标签数量
在编写HTML代码时,需要尽量避免多余的父节点;
很多时候,需要通过迭代和重构来使HTML变得更少。
<!-- Not well -->
<span class="avatar">
<img src="...">
</span>
<!-- Better -->
<img class="avatar" src="...">
实用高于完美
尽量遵循HTML标准和语义,但是不应该以浪费实用性作为代价;
任何时候都要用尽量小的复杂度和尽量少的标签来解决问题。
CSS、 SCSS、 LESS
- 缩进使用soft tab(4个空格);
- 嵌套的节点应该缩进;
- 分号,每个属性声明末尾都要加分号;
- 空格
- 以下几种情况不需要空格:
- 属性名后
- 多个规则的分隔符','前
- !important '!'后
- 属性值中'('后和')'前
- 行末不要有多余的空格
- 以下几种情况需要空格:
- 属性值前
- 选择器'>', '+', '~'前后
- '{'前
- !important '!'前
- @else 前后
- 属性值中的','后
- 注释'/'后和'/'前
- 以下几种情况不需要空格:
- 换行
- 以下几种情况不需要换行:
- '{'前
- 以下几种情况需要换行:
- '{'后和'}'前
- 每个属性独占一行
- 多个规则的分隔符','后
- 以下几种情况不需要换行:
- 注释
- 注释统一用'/**/'(scss中也不要用'//'),具体参照右边的写法;
- 缩进与下一行代码保持一致;
- 可位于一个代码行的末尾,与代码间隔一个空格。
- 命名
- 类名使用小写字母,以中划线分隔
- id采用驼峰式命名
- scss中的变量、函数、混合、placeholder采用驼峰式命名
- 颜色
- 颜色16进制用小写字母;
- 颜色16进制尽量用简写。
.element {
position: absolute;
top: 10px;
left: 10px;
.icon {
font-size: 16px;
}
}
/* not good */
.element {
color :red! important;
background-color: rgba(0,0,0,.5);
}
/* good */
.element {
color: red !important;
background-color: rgba(0, 0, 0, .5);
}
/* not good */
.element ,
.dialog{
...
}
/* good */
.element,
.dialog {
}
/* not good */
.element>.dialog{
...
}
/* good */
.element > .dialog{
...
}
/* not good */
.element{
...
}
/* good */
.element {
...
}
/* not good */
@if{
...
}@else{
...
}
/* good */
@if {
...
} @else {
...
}
/* Modal header */
.modal-header {
/* 50px */
width: 50px;
color: red; /* color red */
}
/* class */
.element-content {
...
}
/* id */
#myDialog {
...
}
/* 变量 */
@colorBlack: #000;
/* not good */
.element {
color: #ABCDEF;
background-color: #001122;
}
/* good */
.element {
color: #abcdef;
background-color: #012;
}
JavaScript
- 缩进,使用soft tab(4个空格);
- 单行长度,不要超过80,但如果编辑器开启word wrap可以不考虑单行长度。
- 分号
- 以下几种情况后需加分号:
- 变量声明
- 表达式
- return
- throw
- break
- continue
- do-while
- 文档注释
- 以下情况下使用:
所有常量、所有函数、所有类
- 以下情况下使用:
- 引号, 最外层统一使用单引号。
- 变量命名
- 标准变量采用驼峰式命名(除了对象的属性外,主要是考虑到cgi返回的数据)
- 'ID'在变量名中全大写
- 'URL'在变量名中全大写
- 'Android'在变量名中大写第一个字母
- 'iOS'在变量名中小写第一个,大写后两个字母
- 常量全大写,用下划线连接
- 构造函数,大写第一个字母
- jquery对象必须以'$'开头命名
// 文档注释
/**
* @func
* @desc 一个带参数的函数
* @param {string} a - 参数a
* @param {number} b=1 - 参数b默认值为1
* @param {string} c=1 - 参数c有两种支持的取值</br>1—表示x</br>2—表示xx
* @param {object} d - 参数d为一个对象
* @param {string} d.e - 参数d的e属性
* @param {string} d.f - 参数d的f属性
* @param {object[]} g - 参数g为一个对象数组
* @param {string} g.h - 参数g数组中一项的h属性
* @param {string} g.i - 参数g数组中一项的i属性
* @param {string} [j] - 参数j是一个可选参数
*/
function foo(a, b, c, d, g, j) {
...
}
// 变量命名
var thisIsMyName;
var goodID;
var reportURL;
var AndroidVersion;
var iOSVersion;
var MAX_COUNT = 10;
function Person(name) {
this.name = name;
}
// not good
var body = $('body');
// good
var $body = $('body');
- null
- 适用场景:
- 初始化一个将来可能被赋值为对象的变量
- 与已经初始化的变量做比较
- 作为一个参数为对象的函数的调用传参
- 作为一个返回对象的函数的返回值
- 不适用场景:
- 不要用null来判断函数调用时有无传参
- 不要与未初始化的变量做比较
- 适用场景:
// not good
function test(a, b) {
if (b === null) {
// not mean b is not supply
...
}
}
var a; // 未初始化
if (a === null) {
...
}
// good
var a = null;
if (a === null) {
...
}
- undefined
- 永远不要直接使用undefined进行变量判断;
- 使用typeof和字符串'undefined'对变量进行判断。
// not good
if (person === undefined) {
...
}
// good
if (typeof person === 'undefined') {
...
}
- jshint
- 用'===', '!=='代替'==', '!=';
- for-in里一定要有hasOwnProperty的判断;
- 不要在内置对象的原型上添加方法,如Array, Date;
- 不要在内层作用域的代码里声明了变量,之后却访问到了外层作用域的同名变量;
- 变量不要先使用后声明;
- 不要在一句代码中单单使用构造函数,记得将其赋值给某个变量;
- 不要在同个作用域下声明同名变量;
- 不要在一些不需要的地方加括号,例:delete(a.b);
- 不要使用未声明的变量(全局变量需要加到.jshintrc文件的globals属性里面);
- 不要声明了变量却不使用;
- 不要在应该做比较的地方做赋值;
- debugger不要出现在提交的代码里;
- 数组中不要存在空元素;
- 不要在循环内部声明函数;
- 不要像这样使用构造函数,例:new function () { ... }, new Object;
// good
for (key in obj) {
if (obj.hasOwnProperty(key)) {
// be sure that obj[key] belongs to the object and was not inherited
console.log(obj[key]);
}
}
// not good
delete(obj.attr);
// good
delete obj.attr;
- 杂项
不要混用tab和space;
不要在一处使用多个tab或space;
换行符统一用'LF';
对上下文this的引用只能使用'_this', 'that', 'self'其中一个来命名;
行尾不要有空白字符;
switch的falling through和no default的情况一定要有注释特别说明;
不允许有空的代码块。
function Person() {
// not good
var me = this;
// good
var _this = this;
// good
var that = this;
// good
var self = this;
}