前端代码规范
<h3>版本记录</h3>
<table>
<thead>
<tr>
<th>版本号</th>
<th>版本说明</th>
<th>作者</th>
<th>日期</th>
<th>备注</th>
</tr>
</thead>
<tbody>
<tr>
<td>V1.0</td>
<td>前端代码规范</td>
<td>Meeler</td>
<td>2018-08-28</td>
<td>修订版</td>
</tr>
<tr>
<td>------------</td>
<td>------------</td>
<td>------------</td>
<td>------------</td>
<td>------------</td>
</tr>
</tbody>
</table>
<h3>$ 原则</h3>
<p><strong>无论团队人数多少,代码应该同出一门。</strong></p>
<hr />
<h2>$ 文件命名规则</h2>
<h4>项目命名</h4>
<p>一律小写;尽量用英文;单词间以下划线分隔。
例:<code>my_project_name</code></p>
<h4>目录命名</h4>
<p>参照项目命名,有复数结构时,要采用复数命名法。
例:<code>scripts, styles, views, images, data_models</code></p>
<h4>JS 文件命名</h4>
<p>参照项目命名规则。
例:<code>query.js, account_model.js</code></p>
<h4>CSS, LESS 文件命名</h4>
<p>参照项目命名规则。
例:<code>retina_sprites.css, base.less</code></p>
<h4>HTML 文件命名</h4>
<p>参照项目命名规则
例:<code>login.html, error_info.html</code></p>
<h4>VUE 模板文件命名</h4>
<p>大驼峰命名
例:<code>Header.vue, StarDetail.vue</code></p>
<p>附:<font color="blue"><strong>常用命名</strong></font></p>
<table>
<thead>
<tr>
<th>1</th>
<th>2</th>
<th>3</th>
<th>4</th>
</tr>
</thead>
<tbody>
<tr>
<td>头:header</td>
<td>内容:content</td>
<td>尾 :footer</td>
<td>导航: nav</td>
</tr>
<tr>
<td>侧栏:sidebar</td>
<td>栏目:column</td>
<td>整体布局:wrapper</td>
<td>容器:container</td>
</tr>
<tr>
<td>登录条:loginbar</td>
<td>标志:logo</td>
<td>广告:banner</td>
<td>主体:main</td>
</tr>
<tr>
<td>热点:hot</td>
<td>新闻:news</td>
<td>下载:download</td>
<td>子导航:subnav</td>
</tr>
<tr>
<td>菜单:menu</td>
<td>子菜单:submenu</td>
<td>搜索:search</td>
<td>链接:link</td>
</tr>
<tr>
<td>版权:copyright</td>
<td>滚动:scroll</td>
<td>内容:content</td>
<td>tab页:tab</td>
</tr>
<tr>
<td>列表:list</td>
<td>信息:msg</td>
<td>提示:tips</td>
<td>标题:title</td>
</tr>
<tr>
<td>加入:joinus</td>
<td>指南:guide</td>
<td>服务:service</td>
<td>注册:register</td>
</tr>
<tr>
<td>状态:status</td>
<td>投票:vote</td>
<td>合作伙伴:partner</td>
<td>位置:left right center</td>
</tr>
</tbody>
</table>
<hr />
<h2>$ JavaScript编码规范</h2>
<h4>缩进</h4>
<p>使用2个空格</p>
<pre><code>var x = 1,
y = 1;
if (x < y) {
x += 10;
} else {
x += 1;
}</code></pre>
<h4>单行长度</h4>
<p>不要超过100,但如果编辑器开启word wrap可以不考虑单行长度。</p>
<h4>分号</h4>
<p>单行语法结束添加分号(统一加)</p>
<pre><code># 以下几种情况后必须加分号:
变量声明 var x = 1;
表达式 x++;
return return false;
throw
break
continue
do-while</code></pre>
<h4>空格</h4>
<ul>
<li>
<p>以下几种情况不需要空格:
1.对象的属性名后
2.前缀一元运算符后
3.后缀一元运算符前
4.函数调用括号前
5.无论是函数声明还是函数表达式,'('前不要空格
6.数组的'['后和']'前
7.对象的'{'后和'}'前
8.运算符'('后和')'前</p>
</li>
<li>以下几种情况需要空格:
1.二元运算符前后
2.三元运算符'?:'前后
3.代码块'{'前
4.下列关键字前:<code>else, while, catch, finally</code>
5.下列关键字后:<code>if, else, for, while, do, switch, case, try, catch, finally, with, return, typeof</code>
6.单行注释'//'后;若单行注释和代码同行,则'//'前也需要
7.多行注释'*'后对象的属性值前
7.for循环,分号后留有一个空格,前置条件如果有多个,逗号后留一个空格
8.无论是函数声明还是函数表达式,'{'前一定要有空格
9.函数的参数之间有空格</li>
</ul>
<pre><code>// not good
var a = {
b :1
};
// good
var a = {
b: 1
};
// not good
++ x;
y ++;
z = x?1:2;
// good
++x;
y++;
z = x ? 1 : 2;
// not good
var a = [ 1, 2 ];
// good
var a = [1, 2];
// not good
var a = ( 1+2 )*3;
// good
var a = (1 + 2) * 3;
// no space before '(', one space before '{', one space between function parameters
var doSomething = function(a, b, c) {
// do something
};
// no space before '('
doSomething(item);
// not good
for(i=0;i<6;i++){
x++;
}
// good
for (i = 0; i < 6; i++) {
x++;
}</code></pre>
<h4>空行</h4>
<ul>
<li>以下几种情况需要空行:
1.变量声明后(当变量声明在代码块的最后一行时,则无需空行)
2.注释前(当注释在代码块的第一行时,则无需空行)
3.代码块后(在函数调用、数组、对象中则无需空行)
4.文件最后保留一个空行</li>
</ul>
<h4>换行</h4>
<p><font color="blue">换行的地方,行末必须有','或者运算符。</font></p>
<ul>
<li>
<p>以下几种情况不需要换行:
1.下列关键字后:<code>else, catch, finally</code>
2.代码块'{'前</p>
</li>
<li>以下几种情况需要换行:
1.代码块'{'后和'}'前
2.变量赋值后</li>
</ul>
<h4>单行注释</h4>
<ul>
<li>双斜线后,必须跟一个空格;</li>
<li>缩进与下一行代码保持一致;</li>
<li>可位于一个代码行的末尾,与代码间隔一个空格。</li>
</ul>
<pre><code>if (condition) {
// if you made it here, then all security checks passed
allowed();
}
var zhangsan = 'zhangsan'; // one space after code</code></pre>
<h4>多行注释</h4>
<ul>
<li>
<p>最少三行, '*'后跟一个空格,具体参照右边的写法;</p>
</li>
<li>建议在以下情况下使用:
1.难于理解的代码段
2.可能存在错误的代码段
3.浏览器特殊的HACK代码
4.业务逻辑强相关的代码</li>
</ul>
<pre><code>/*
* one space after '*'
*/
var x = 1;</code></pre>
<h4>文档注释</h4>
<ul>
<li>
<p>各类标签@param, @method等请参考<a href="http://usejsdoc.org/" title="usejsdoc">usejsdoc</a>和<a href="http://yuri4ever.github.io/jsdoc/" title="JSDoc Guide">JSDoc Guide</a>;</p>
</li>
<li>建议在以下情况下使用:
a.所有常量
b.所有函数
c.所有类</li>
</ul>
<pre><code>/**
* @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) {
...
}</code></pre>
<h4>引号</h4>
<p><font color="red"><strong>最外层统一使用单引号。</strong></font></p>
<pre><code>// not good
var x = "test";
// good
var y = 'foo',
z = '<div id="test"></div>';</code></pre>
<h4>变量命名</h4>
<p><font color="blue">标准变量采用<strong>驼峰式命名</strong></font>(除了对象的属性外,主要是考虑到cgi返回的数据)</p>
<ul>
<li>
<p>'ID'在变量名中全大写</p>
</li>
<li>
<p>'URL'在变量名中全大写</p>
</li>
<li>
<p>'Android'在变量名中大写第一个字母</p>
</li>
<li>
<p>'iOS'在变量名中小写第一个,大写后两个字母</p>
</li>
<li>
<p>常量全大写,用下划线连接</p>
</li>
<li>
<p>构造函数,大写第一个字母</p>
</li>
<li>jquery对象必须以'$'开头命名</li>
</ul>
<pre><code>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');</code></pre>
<h4>变量声明</h4>
<p>一个函数作用域中所有的变量声明尽量提到函数首部,用一个var声明,<font color="red">不允许出现两个连续的var声明</font>。</p>
<pre><code>function doSomethingWithItems(items) {
// use one var
var value = 10,
result = value + 10,
i,
len;
for (i = 0, len = items.length; i < len; i++) {
result += 10;
}
}</code></pre>
<h4>函数</h4>
<ul>
<li>
<p>无论是函数声明还是函数表达式,'('前不要空格,但'{'前一定要有空格;</p>
</li>
<li>
<p>函数调用括号前不需要空格;</p>
</li>
<li>
<p>立即执行函数外必须包一层括号;</p>
</li>
<li>
<p>不要给inline function命名;</p>
</li>
<li>参数之间用', '分隔,注意逗号后有一个空格。</li>
</ul>
<h4>数组、对象</h4>
<ul>
<li>
<p><font color="red"><strong>对象属性名不需要加引号</strong></font>;</p>
</li>
<li>
<p>对象以缩进的形式书写,不要写在一行;</p>
</li>
<li>数组、对象最后不要有逗号。</li>
</ul>
<pre><code>// not good
var a = {
'b': 1
};
var a = {b: 1};
var a = {
b: 1,
c: 2,
};
// good
var a = {
b: 1,
c: 2
};</code></pre>
<h4>括号</h4>
<p>下列关键字后必须有大括号(即使代码块的内容只有一行):<code>if, else, for, while, do, switch, try, catch, finally, with</code></p>
<h4>null</h4>
<ul>
<li>
<p>适用场景:
a.初始化一个将来可能被赋值为对象的变量
b.与已经初始化的变量做比较
c.作为一个参数为对象的函数的调用传参
d.作为一个返回对象的函数的返回值</p>
</li>
<li>不适用场景:
a.不要用null来判断函数调用时有无传参
b.不要与未初始化的变量做比较</li>
</ul>
<pre><code>// 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) {
...
}</code></pre>
<h4>undefined</h4>
<ul>
<li>
<p>永远不要直接使用undefined进行变量判断;</p>
</li>
<li>使用typeof和字符串'undefined'对变量进行判断。</li>
</ul>
<pre><code>// not good
if (person === undefined) {
...
}
// good
if (typeof person === 'undefined') {
...
}</code></pre>
<h4>其他</h4>
<ul>
<li>
<p><strong>用'===', '!=='代替'==', '!='</strong>;</p>
</li>
<li>
<p><strong> for-in里一定要有hasOwnProperty的判断</strong>;</p>
</li>
<li>
<p>不要在内置对象的原型上添加方法,如Array, Date;</p>
</li>
<li>
<p>不要在内层作用域的代码里声明了变量,之后却访问到了外层作用域的同名变量;</p>
</li>
<li>
<p><strong>变量不要先使用后声明</strong>;</p>
</li>
<li>
<p>不要在一句代码中单单使用构造函数,记得将其赋值给某个变量;</p>
</li>
<li>
<p>不要在同个作用域下声明同名变量;</p>
</li>
<li>
<p>不要在一些不需要的地方加括号,例:delete(a.b);</p>
</li>
<li>
<p>不要使用未声明的变量(全局变量需要加到.jshintrc文件的globals属性里面);</p>
</li>
<li>
<p>不要声明了变量却不使用;</p>
</li>
<li>
<p><strong>不要在应该做比较的地方做赋值</strong>;</p>
</li>
<li>
<p>debugger不要出现在提交的代码里;</p>
</li>
<li>
<p><strong>数组中不要存在空元素</strong>;</p>
</li>
<li>
<p>不要在循环内部声明函数;</p>
</li>
<li>
<p>不要像这样使用构造函数,例:<code>new function () { ... }, new Object</code></p>
</li>
<li>
<p>不要混用tab和space;</p>
</li>
<li>
<p>不要在一处使用多个tab或space;</p>
</li>
<li>
<p>换行符统一用'LF';</p>
</li>
<li>
<p><strong>对上下文this的引用只能使用'_this', 'that', 'self'其中一个来命名</strong>;</p>
</li>
<li>
<p><strong>行尾不要有空白字符</strong>;</p>
</li>
<li>
<p>switch的falling through和no default的情况一定要有注释特别说明;</p>
</li>
<li>不允许有空的代码块。</li>
</ul>
<hr />
<h2>$ CSS编码规范</h2>
<h4>缩进</h4>
<p>使用2个空格</p>
<h4>分号</h4>
<p>每个属性声明末尾都要加分号。</p>
<pre><code>.element {
width: 20px;
height: 20px;
background-color: red;
}</code></pre>
<h4>空格</h4>
<ul>
<li>
<p>以下几种情况不需要空格:
a.属性名后
b.多个规则的分隔符','前
c.!important '!'后
d.属性值中'('后和')'前
e.行末不要有多余的空格</p>
</li>
<li>以下几种情况需要空格:
a.属性值前
b.选择器'>', '+', '~'前后
c.'{'前
d.!important '!'前
e.else 前后
f.属性值中的','后
g.注释'/<em>'后和'</em>/'前</li>
</ul>
<h4>属性声明顺序</h4>
<p>相关的属性声明按如下的顺序做分组处理,组之间需要有一个空行。(<font color="red">同类型一起即可,不用严格按照顺序</font>)</p>
<pre><code>.declaration-order {
display: block;
float: right;
// <空行>
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 100;
// <空行>
border: 1px solid #e5e5e5;
border-radius: 3px;
width: 100px;
height: 100px;
// <空行>
font: normal 13px "Helvetica Neue", sans-serif;
line-height: 1.5;
text-align: center;
// <空行>
color: #333;
background-color: #f5f5f5;
// <空行>
opacity: 1;
}
// 下面是推荐的属性的顺序
[
[
"display",
"visibility",
"float",
"clear",
"overflow",
"overflow-x",
"overflow-y",
"clip",
"zoom"
],
[
"table-layout",
"empty-cells",
"caption-side",
"border-spacing",
"border-collapse",
"list-style",
"list-style-position",
"list-style-type",
"list-style-image"
],
[
"-webkit-box-orient",
"-webkit-box-direction",
"-webkit-box-decoration-break",
"-webkit-box-pack",
"-webkit-box-align",
"-webkit-box-flex"
],
[
"position",
"top",
"right",
"bottom",
"left",
"z-index"
],
[
"margin",
"margin-top",
"margin-right",
"margin-bottom",
"margin-left",
"-webkit-box-sizing",
"-moz-box-sizing",
"box-sizing",
"border",
"border-width",
"border-style",
"border-color",
"border-top",
"border-top-width",
"border-top-style",
"border-top-color",
"border-right",
"border-right-width",
"border-right-style",
"border-right-color",
"border-bottom",
"border-bottom-width",
"border-bottom-style",
"border-bottom-color",
"border-left",
"border-left-width",
"border-left-style",
"border-left-color",
"-webkit-border-radius",
"-moz-border-radius",
"border-radius",
"-webkit-border-top-left-radius",
"-moz-border-radius-topleft",
"border-top-left-radius",
"-webkit-border-top-right-radius",
"-moz-border-radius-topright",
"border-top-right-radius",
"-webkit-border-bottom-right-radius",
"-moz-border-radius-bottomright",
"border-bottom-right-radius",
"-webkit-border-bottom-left-radius",
"-moz-border-radius-bottomleft",
"border-bottom-left-radius",
"-webkit-border-image",
"-moz-border-image",
"-o-border-image",
"border-image",
"-webkit-border-image-source",
"-moz-border-image-source",
"-o-border-image-source",
"border-image-source",
"-webkit-border-image-slice",
"-moz-border-image-slice",
"-o-border-image-slice",
"border-image-slice",
"-webkit-border-image-width",
"-moz-border-image-width",
"-o-border-image-width",
"border-image-width",
"-webkit-border-image-outset",
"-moz-border-image-outset",
"-o-border-image-outset",
"border-image-outset",
"-webkit-border-image-repeat",
"-moz-border-image-repeat",
"-o-border-image-repeat",
"border-image-repeat",
"padding",
"padding-top",
"padding-right",
"padding-bottom",
"padding-left",
"width",
"min-width",
"max-width",
"height",
"min-height",
"max-height"
],
[
"font",
"font-family",
"font-size",
"font-weight",
"font-style",
"font-variant",
"font-size-adjust",
"font-stretch",
"font-effect",
"font-emphasize",
"font-emphasize-position",
"font-emphasize-style",
"font-smooth",
"line-height",
"text-align",
"-webkit-text-align-last",
"-moz-text-align-last",
"-ms-text-align-last",
"text-align-last",
"vertical-align",
"white-space",
"text-decoration",
"text-emphasis",
"text-emphasis-color",
"text-emphasis-style",
"text-emphasis-position",
"text-indent",
"-ms-text-justify",
"text-justify",
"letter-spacing",
"word-spacing",
"-ms-writing-mode",
"text-outline",
"text-transform",
"text-wrap",
"-ms-text-overflow",
"text-overflow",
"text-overflow-ellipsis",
"text-overflow-mode",
"-ms-word-wrap",
"word-wrap",
"-ms-word-break",
"word-break"
],
[
"color",
"background",
"filter:progid:DXImageTransform.Microsoft.AlphaImageLoader",
"background-color",
"background-image",
"background-repeat",
"background-attachment",
"background-position",
"-ms-background-position-x",
"background-position-x",
"-ms-background-position-y",
"background-position-y",
"-webkit-background-clip",
"-moz-background-clip",
"background-clip",
"background-origin",
"-webkit-background-size",
"-moz-background-size",
"-o-background-size",
"background-size"
],
[
"outline",
"outline-width",
"outline-style",
"outline-color",
"outline-offset",
"opacity",
"filter:progid:DXImageTransform.Microsoft.Alpha(Opacity",
"-ms-filter:\\'progid:DXImageTransform.Microsoft.Alpha",
"-ms-interpolation-mode",
"-webkit-box-shadow",
"-moz-box-shadow",
"box-shadow",
"filter:progid:DXImageTransform.Microsoft.gradient",
"-ms-filter:\\'progid:DXImageTransform.Microsoft.gradient",
"text-shadow"
],
[
"-webkit-transition",
"-moz-transition",
"-ms-transition",
"-o-transition",
"transition",
"-webkit-transition-delay",
"-moz-transition-delay",
"-ms-transition-delay",
"-o-transition-delay",
"transition-delay",
"-webkit-transition-timing-function",
"-moz-transition-timing-function",
"-ms-transition-timing-function",
"-o-transition-timing-function",
"transition-timing-function",
"-webkit-transition-duration",
"-moz-transition-duration",
"-ms-transition-duration",
"-o-transition-duration",
"transition-duration",
"-webkit-transition-property",
"-moz-transition-property",
"-ms-transition-property",
"-o-transition-property",
"transition-property",
"-webkit-transform",
"-moz-transform",
"-ms-transform",
"-o-transform",
"transform",
"-webkit-transform-origin",
"-moz-transform-origin",
"-ms-transform-origin",
"-o-transform-origin",
"transform-origin",
"-webkit-animation",
"-moz-animation",
"-ms-animation",
"-o-animation",
"animation",
"-webkit-animation-name",
"-moz-animation-name",
"-ms-animation-name",
"-o-animation-name",
"animation-name",
"-webkit-animation-duration",
"-moz-animation-duration",
"-ms-animation-duration",
"-o-animation-duration",
"animation-duration",
"-webkit-animation-play-state",
"-moz-animation-play-state",
"-ms-animation-play-state",
"-o-animation-play-state",
"animation-play-state",
"-webkit-animation-timing-function",
"-moz-animation-timing-function",
"-ms-animation-timing-function",
"-o-animation-timing-function",
"animation-timing-function",
"-webkit-animation-delay",
"-moz-animation-delay",
"-ms-animation-delay",
"-o-animation-delay",
"animation-delay",
"-webkit-animation-iteration-count",
"-moz-animation-iteration-count",
"-ms-animation-iteration-count",
"-o-animation-iteration-count",
"animation-iteration-count",
"-webkit-animation-direction",
"-moz-animation-direction",
"-ms-animation-direction",
"-o-animation-direction",
"animation-direction"
],
[
"content",
"quotes",
"counter-reset",
"counter-increment",
"resize",
"cursor",
"-webkit-user-select",
"-moz-user-select",
"-ms-user-select",
"user-select",
"nav-index",
"nav-up",
"nav-right",
"nav-down",
"nav-left",
"-moz-tab-size",
"-o-tab-size",
"tab-size",
"-webkit-hyphens",
"-moz-hyphens",
"hyphens",
"pointer-events"
]
]</code></pre>
<h4>空行</h4>
<ul>
<li>
<p>文件最后保留一个空行;</p>
</li>
<li>
<p>'}'后最好跟一个空行,包括scss中嵌套的规则;</p>
</li>
<li>属性之间需要适当的空行,具体见上述属性声明顺序。</li>
</ul>
<h4>换行</h4>
<ul>
<li>
<p>以下几种情况不需要换行:
'{'前</p>
</li>
<li>以下几种情况需要换行:
a.'{'后和'}'前
b.每个属性独占一行
c.多个规则的分隔符','后</li>
</ul>
<pre><code>/* not good */
.element
{color: red; background-color: black;}
/* good */
.element {
color: red;
background-color: black;
}
/* not good */
.element, .dialog {
...
}
/* good */
.element,
.dialog {
...
}</code></pre>
<h4>注释</h4>
<ul>
<li>
<p><font color="red"><strong>注释统一用'/<em> </em>/'</strong></font>,具体参照右边的写法;</p>
</li>
<li>
<p>缩进与下一行代码保持一致;</p>
</li>
<li>可位于一个代码行的末尾,与代码间隔一个空格。</li>
</ul>
<h4>引号</h4>
<ul>
<li>
<p><font color="red">最外层统一使用双引号</font>;</p>
</li>
<li>
<p>url的内容要用引号;</p>
</li>
<li>属性选择器中的属性值需要引号。</li>
</ul>
<pre><code>.element:after {
content: "";
background-image: url("logo.png");
}
li[data-type="single"] {
...
}</code></pre>
<h4>ID命名</h4>
<p>id采用驼峰式命名</p>
<pre><code>/* id */
#myDialog {
...
}</code></pre>
<h4>变量、函数等命名</h4>
<p>scss/less中的变量、函数、混合、placeholder采用驼峰式命名</p>
<pre><code>/* 变量 */
$colorBlack: #000;
/* 函数 */
@function pxToRem($px) {
...
}
/* 混合 */
@mixin centerBlock {
...
}
/* placeholder */
%myDialog {
...
}</code></pre>
<h4>class 命名</h4>
<ul>
<li>使用BEM书写规范,BEM分别代表“块(block),元素(element),修饰符(modifier)”。</li>
<li>.less 文件的引用顺序会对最终编译的样式的作用域和优先级产生影响,请尽量按照由底层到自定义的顺序来引用。</li>
<li>使用BEM原则,用命名来解耦,所有类名都为一层,增加效率和复用性。</li>
<li>组件之间的完全解耦,不会造成命名空间的污染,如:.mod-xxx ul li 的写法带来的潜在的嵌套风险。</li>
<li>BEM 命名会使得 Class 类名变长,但经过 gzip 压缩后这个带宽开销可以忽略不计。</li>
</ul>
<p>在选择器中,由以下三种符合来表示扩展的关系:</p>
<pre><code># 中划线 `-` :仅作为连字符,表示某个块或者某个子元素的多单词之间的连接记号。
# 双下划线 `__` :双下划线用来连接块和块的子元素。
# 单下划线 `_` :单下划线用来描述一个块或者块的子元素的一种状态。
`.list{ }
.list__item{ }
.list__item_hightlight{ }
.list__product-name{ }
.list__link{ }
.list__ming-zi-ke-yi-hen-chang{ }
// 嵌套写法
.list__item_current{
.list__link{ }
}`
# 颜色:使用颜色的名称或者16进制代码,如
`.red { color: red; }
.f60 { color: #f60; }
.ff8600 { color: #ff8600; }`
# 字体大小,直接使用”font+字体大小”作为名称,如
`.font12px { font-size: 12px; }
.font9pt {font-size: 9pt; }`
# 对齐样式,使用对齐目标的英文名称,如
`.left { float:left; }
.bottom { float:bottom; }`
# 标题栏样式,使用”类别+功能”的方式命名,如
`.bar-news { }
.bar-product { }`</code></pre>
<h4>属性简写</h4>
<p><font color="red"> 属性简写需要你非常清楚属性值的正确顺序,而且在大多数情况下并不需要设置属性简写中包含的所有值,所以建议尽量分开声明会更加清晰</font>。</p>
<ul>
<li>
<p>margin 和 padding 相反,需要使用简写;</p>
</li>
<li>常见的属性简写包括:
font
background
transition
animation</li>
</ul>
<pre><code>/* not good */
.element {
transition: opacity 1s linear 2s;
}
/* good */
.element {
transition-delay: 2s;
transition-timing-function: linear;
transition-duration: 1s;
transition-property: opacity;
}</code></pre>
<h4>媒体查询</h4>
<p>尽量将媒体查询的规则靠近与他们相关的规则,不要将他们一起放到一个独立的样式文件中,或者丢在文档的最底部,这样做只会让大家以后更容易忘记他们。</p>
<pre><code>.element {
...
}
.element-avatar{
...
}
@media (min-width: 480px) {
.element {
...
}
.element-avatar {
...
}
}</code></pre>
<h3>其他</h3>
<ul>
<li>
<p>不允许有空的规则;</p>
</li>
<li>
<p>元素选择器用小写字母;</p>
</li>
<li>
<p><strong>去掉小数点前面的0</strong>;</p>
</li>
<li>
<p><strong>去掉数字中不必要的小数点和末尾的0</strong>;</p>
</li>
<li>
<p><strong>属性值'0'后面不要加单位</strong>;</p>
</li>
<li>
<p>同个属性不同前缀的写法需要在垂直方向保持对齐,具体参照右边的写法;</p>
</li>
<li>
<p>无前缀的标准属性应该写在有前缀的属性后面;</p>
</li>
<li>
<p>不要在同个规则里出现重复的属性,如果重复的属性是连续的则没关系;</p>
</li>
<li>
<p>不要在一个文件里出现两个相同的规则;</p>
</li>
<li>
<p><strong>用 border: 0; 代替 border: none</strong>;</p>
</li>
<li>
<p><strong>选择器不要超过4层(在less中如果超过4层应该考虑用嵌套的方式来写)</strong>;</p>
</li>
<li>尽量少用'*'选择器。</li>
</ul>
<pre><code>/* not good */
.element {
color: rgba(0, 0, 0, 0.5);
}
/* good */
.element {
color: rgba(0, 0, 0, .5);
}
/* not good */
.element {
color: rgb(0, 0, 0);
width: 50px;
color: rgba(0, 0, 0, .5);
}
/* good */
.element {
color: rgb(0, 0, 0);
color: rgba(0, 0, 0, .5);
width: 50px;
}</code></pre>
<hr />
<h2>$ HTML编码规范</h2>
<h4>语法</h4>
<ul>
<li>
<p>缩进使用2个空格;</p>
</li>
<li>
<p>嵌套的节点应该缩进;</p>
</li>
<li>
<p>在属性上,使用双引号,不要使用单引号;</p>
</li>
<li>
<p>属性名全小写,用中划线做分隔符;</p>
</li>
<li>
<p>不要在自动闭合标签结尾处使用斜线;</p>
</li>
<li>不要忽略可选的关闭标签,例:<code></li> 和 </body></code>。</li>
</ul>
<h4>字符编码</h4>
<p>通过声明一个明确的字符编码,让浏览器轻松、快速的确定适合网页内容的渲染方式,通常指定为'UTF-8'。</p>
<pre><code><!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
...
</html></code></pre>
<h4>IE兼容模式</h4>
<p>用 <code><meta></code>标签可以指定页面应该用什么版本的IE来渲染。</p>
<pre><code><!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
</head>
...
</html></code></pre>
<h4>引入CSS, JS</h4>
<p>根据HTML5规范, 通常在引入CSS和JS时不需要指明 type,因为 text/css 和 text/javascript 分别是他们的默认值。
HTML5 规范链接:<code>使用link,使用style,使用script</code></p>
<pre><code><!-- 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></code></pre>
<h4>属性</h4>
<p><font color="blue">属性应该按照特定的顺序出现以保证易读性</font>;
<font color="red">属性必须用双引号,内部可嵌套单引号(与JS相反)</font>;</p>
<ul>
<li>class 是为高可复用组件设计的,所以应处在第一位;</li>
<li>id 更加具体且应该尽量少使用,所以将它放在第二位。
class
id
name
data-<em>
src, for, type, href, value , max-length, max, min, pattern
placeholder, title, alt
aria-</em>, role
required, readonly, disabled</li>
</ul>
<pre><code><a class="..." id="..." data-modal="toggle" href="#">Example link</a>
<input class="form-control" type="text">
<img src="..." alt="..."></code></pre>
<h4>减少标签数量</h4>
<p>在编写HTML代码时,需要尽量避免多余的父节点;很多时候,需要通过迭代和重构来使HTML变得更少。</p>
<pre><code><!-- Not well -->
<span class="avatar">
<img src="...">
</span>
<!-- Better -->
<img class="avatar" src="..."></code></pre>
<hr />
<h2>$ VUE编码规范</h2>
<h4>组件命名规范</h4>
<ul>
<li>
<p>Vue官方文档给予以下说明:</p>
<pre><code>当注册组件 (或者 prop) 时,可以使用 kebab-case (短横线分隔命名)、camelCase (驼峰式命名) 或 PascalCase (单词首字母大写命名)。
PascalCase 是最通用的声明约定而 kebab-case 是最通用的使用约定。</code></pre>
</li>
<li>命名可遵循以下规则:
<pre><code>1、有意义的名词、简短、具有可读性
2、以小写开头,采用短横线分割命名
3、公共组件命名以公司名称简拼为命名空间(app-xx.vue)
4、文件夹命名主要以功能模块代表命名
5、必须符合自定义元素规范: 使用连字符分隔单词,切勿使用保留字。app- 前缀作为命名空间: 如果非常通用的话可使用一个单词来命名,这样可以方便于其它项目里复用。</code></pre></li>
</ul>
<h4>VUE木板文件</h4>
<ul>
<li>
<p>文件基本结构</p>
<pre><code><template>
<div>
<!--必须在div中编写页面-->
</div>
</template>
<script>
export default {
components : {
},
data () {
return {
}
},
methods: {
},
mounted() {
}
}
</script>
<!--声明语言,并且添加scoped-->
<style lang="less" scoped>
</style></code></pre>
</li>
<li>文件方法声明顺序
<pre><code>- components
- props
- data
- created
- mounted
- activited
- update
- beforeRouteUpdate
- metods
- filter
- computed
- watch</code></pre></li>
</ul>
<h4>注释规范</h4>
<p>代码注释在一个项目的后期维护中显的尤为重要,所以我们要为每一个被复用的组件编写组件使用说明,为组件中每一个方法编写方法说明。</p>
<ul>
<li>以下情况,务必添加注释
1.公共组件使用说明
2.各组件中重要函数或者类说明
3.复杂的业务逻辑处理说明
4.特殊情况的代码处理说明,对于代码中特殊用途的变量、存在临界值、函数中使用的hack、使用了某种算法或思路等需要进行注释描述
5.注释块必须以至少两个星号开头<code>/ ** 注释 **/</code>;
6.单行注释使用//;</li>
</ul>
<pre><code> # 多行注释:组件使用说明,和调用说明
<!--公用组件:数据表格
/**
* 组件名称
* @module 组件存放位置
* @desc 组件描述
* @author 组件作者
* @date 2017年12月05日17:22:43
* @param {Object} [title] - 参数说明
* @param {String} [columns] - 参数说明
* @example 调用示例
* <hbTable :title="title" :columns="columns" :tableData="tableData"></hbTable>
**/
--></code></pre>
<h4>script编码规范</h4>
<ol>
<li>使用ES6风格编码
a.定义变量使用let ,定义常量使用const
b.使用export ,import 模块化
c.class、extends、super
d.arrow functions (箭头函数)
e.template string (模板字符串)
f.优先使用解构赋值</li>
</ol>
<pre><code>// ES6 箭头22函数
let arr2 = [1, 2, 3];
let newArr2 = arr2.map((x) => {
x + 1
});
// 模板字符串
1. 字符串拼接。将表达式嵌入字符串中进行拼接,用 ` 和${}`来界定;
const name2 = "ming";
console.log(`hello${name2}`);
2. 做多行字符串拼接
const template = `<div>
<span>hello world</span>
</div>`;
// 优先使用解构赋值
const arr = [1, 2, 3, 4];
// bad
const first = arr[0];
const second = arr[1];
// good
const [first, second] = arr;
// 函数的参数如果是对象的成员,优先使用解构赋值。
// bad
function getFullName(user) {
const firstName = user.firstName;
const lastName = user.lastName;
}
// good
function getFullName(obj) {
const { firstName, lastName } = obj;
}
// best
function getFullName({ firstName, lastName }) {
}
// 描述尽可能短
const lukeSky = 'Luke sky';
// bad
const obj = {
lukeSky : lukeSky,
}
// good
const obj = {
lukeSky
}
// 对象copy 正确姿势
// very bad
const original = { a:1,b:2 };
const copy = Object.assign( original ,{ c:3 });
delete copy.a ; //
// bad
const original = { a:1,b:2 }
const copy = Object.assign( {},original,{ c:3 });
// good !!!!!
const original = { a:1,b:2}
const copy = { ...original, c:3 }; // copy => { a:1,b:2,c:3 }
const { a, ...noA } = copy; // noA => { b:2 ,c:3 }</code></pre>
<ol>
<li>
<p>组件 props 原子化
提供默认值
使用 type 属性校验类型
使用 props 之前先检查该 prop 是否存在</p>
</li>
<li>
<p>避免 this.$parent
同一个页面this的指代_this、that、self只能一个。</p>
</li>
<li>
<p>谨慎使用 this.$refs</p>
</li>
<li>
<p>无需将 this 赋值给 component 变量</p>
</li>
<li>
<p>调试信息console.log() debugger 使用完及时删除</p>
</li>
<li>其他参考JavaScript编码规范</li>
</ol>