一撼短、概述
本規(guī)范旨在為前端程序的開(kāi)發(fā)者提供規(guī)范化最新的指導(dǎo),可用于程序員個(gè)人編譯環(huán)境以及研發(fā)團(tuán)隊(duì)集成環(huán)境等場(chǎng)合的代碼規(guī)范化檢查挺勿。
不管有多少人共同參與同一項(xiàng)目曲横,一定要確保每一行代碼都像是同一個(gè)人編寫的
二、方針
約束等級(jí) | 約束效力 | 強(qiáng)制性 |
---|---|---|
【強(qiáng)制】 | 違反該項(xiàng)將被認(rèn)為代碼存在嚴(yán)重缺陷 | 前端程序團(tuán)隊(duì)必須遵守 |
【推薦】 | 違反該項(xiàng)將被認(rèn)為代碼存在輕微缺陷 | 根據(jù)具體產(chǎn)品特性的不同不瓶,選擇性地遵守 |
【參考】 | 違反該項(xiàng)可被認(rèn)為代碼存在優(yōu)化空間 | 從產(chǎn)品持續(xù)優(yōu)化及人員技能提升的角度禾嫉,參考使用 |
三、環(huán)境要求
【強(qiáng)制】Node.js 8.9 或更高版本湃番,你可以使用 nvm 或 nvm-windows 在一臺(tái)電腦中管理多個(gè) Node 版本
【強(qiáng)制】使用 Visual Studio Code (VS Code) 進(jìn)行代碼編寫
【強(qiáng)制】代碼提交前使用 VS Code 進(jìn)行格式化(不要格式引入的外部文件)
【強(qiáng)制】規(guī)定 Tab 大小為 2 個(gè)空格夭织,保證在所有環(huán)境下獲得一致展現(xiàn)
// settings.json
{
"editor.tabSize": 2
// ...
}
【強(qiáng)制】安裝插件 Vetur( Vue開(kāi)發(fā)擴(kuò)展及 Vue 文件代碼格式化)
【強(qiáng)制】安裝插件 Prettier - Code formatter( CSS / Less / JS 等其他文件代碼格式化;Vetur 的格式化基于此插件實(shí)現(xiàn)吠撮,固可以在所有文件實(shí)現(xiàn)統(tǒng)一的格式化)
【推薦】安裝插件 Chinese (Simplified) Language Pack for Visual Studio Code ( VS Code 簡(jiǎn)體中文語(yǔ)言包)
【推薦】使用 Chrome 瀏覽器并安裝 Vue.js devtools 進(jìn)行調(diào)試
四、編碼規(guī)范
4.1 HTML / Template 編碼規(guī)范
- 【強(qiáng)制】縮進(jìn)使用兩個(gè)空格代替 Tab
- 前端代碼層級(jí)較深讲竿,使用短縮進(jìn)有利于利用屏幕空間泥兰,提升效率
- 使用兩個(gè)空格代替 Tab 可以保證在所有環(huán)境下獲得一致展現(xiàn)
<!-- not good -->
<div>
<div>bar</div>
</div>
<!-- good -->
<div>
<div>bar</div>
</div>
- 【強(qiáng)制】嵌套元素應(yīng)當(dāng)縮進(jìn)一次(即兩個(gè)空格),同層級(jí)縮進(jìn)應(yīng)保持一致
<!-- not good -->
<div>
<div>bar</div>
<div>bar</div>
</div>
<!-- good -->
<div>
<div>bar</div>
<div>bar</div>
</div>
- 【強(qiáng)制】對(duì)于屬性的定義题禀,使用雙引號(hào)鞋诗,不要使用單引號(hào)
<!-- not good -->
<input class='a' type=text>
<!-- good -->
<input class="a" type="text">
- 【強(qiáng)制】不要省略可選的結(jié)束標(biāo)簽(closing tag)(如</li> 或 </body>)
省略可選的結(jié)束標(biāo)簽,雖不會(huì)違反 H5 規(guī)范迈嘹;但可能會(huì)造成層級(jí)上的困擾削彬,導(dǎo)致代碼出現(xiàn)無(wú)法預(yù)料的問(wèn)題
<!-- not good -->
<h1>h1 text
<h2>h2 text
<!-- good -->
<h1>h1 text</h1>
<h2>h2 text</h2>
- 【強(qiáng)制】特殊符號(hào)使用 HTML 字符實(shí)體(實(shí)體名稱對(duì)大小寫敏感),常用如下:
符號(hào) | 實(shí)體編碼 |
---|---|
空格 | |
? | © |
¥ | ¥ |
? | ® |
> | ® |
< | < |
& | & |
- 【強(qiáng)制】td / th 要在 tr 里面秀仲,li 要在 ul / ol 里面
<!-- not good -->
<table>
<td>test</td>
</table>
<!-- good -->
<table>
<tr>
<td>test</td>
</tr>
</table>
- 【強(qiáng)制】ul / ol 的直接子元素只能是 li融痛,不能包含其他元素
<!-- not good -->
<ul>
<span>123</span>
<li>a</li>
<li>b</li>
</ul>
- 【強(qiáng)制】行內(nèi)元素里面不可使用塊級(jí)元素
a 標(biāo)簽是一個(gè)行內(nèi)元素,行內(nèi)元素里面套了一個(gè) div 的標(biāo)簽神僵,這樣可能會(huì)導(dǎo)致 a 標(biāo)簽無(wú)法正常點(diǎn)擊
<!-- not good -->
<a href="../test">
<div></div>
</a>
可以使用如下代碼進(jìn)行修復(fù):
<a href="../test" style="display: block">
<div></div>
</a>
- 【強(qiáng)制】不使用自定義標(biāo)簽雁刷,會(huì)與Vue組件系統(tǒng)的自定義組件沖突
- 【強(qiáng)制】不使用重復(fù)屬性,重復(fù)的屬性只會(huì)取第一個(gè)
<!-- error -->
<input class="a" type="text" class="b">
<!-- good -->
<input class="a b" type="text">
- 【強(qiáng)制】不要在https的鏈接里寫http的圖片
只要https的網(wǎng)頁(yè)請(qǐng)求了一張http的圖片保礼,就會(huì)導(dǎo)致瀏覽器地址欄左邊的小鎖沒(méi)有了沛励,一般不要寫死,寫成根據(jù)當(dāng)前域名的協(xié)議去加載炮障,用//開(kāi)頭:
<img src="http://static.chimeroi.com/hello-world.jpg">
- 【推薦】不要在自閉合(self-closing)元素的尾部添加斜線( HTML5 規(guī)范中說(shuō)明這是可選的)
<!-- not good -->
<img src="logo.png" alt />
<!-- good -->
<img src="logo.png" alt>
- 【推薦】不使用屬性設(shè)置樣式(img, table等元素)
<!-- not good -->
<img src="test.jpg" alt width="400" height="300">
<!-- good -->
<img src="test.jpg" style="width:400px;height:300px;">
- 【參考】自定義屬性要以data-開(kāi)頭 自己添加的非標(biāo)準(zhǔn)的屬性要以data-開(kāi)頭目派,否則w3c validator會(huì)認(rèn)為是不規(guī)范的
<!-- not good -->
<div count="5"></div>
<!-- good -->
<div data-count="5"></div>
HTML5 doctype
【強(qiáng)制】為每個(gè) HTML 頁(yè)面添加標(biāo)準(zhǔn)模式(standard mode)的聲明,確保在每個(gè)瀏覽器中擁有一致的展現(xiàn)
<!DOCTYPE html>
<html>
...
語(yǔ)言屬性
【強(qiáng)制】為每個(gè) HTML 頁(yè)面根元素添加 lang 屬性
根據(jù) HTML5 規(guī)范:
強(qiáng)烈建議為 html 根元素指定 lang 屬性胁赢,從而為文檔設(shè)置正確的語(yǔ)言企蹭。這將有助于語(yǔ)音合成工具確定其所應(yīng)該采用的發(fā)音,有助于翻譯工具確定其翻譯時(shí)所應(yīng)遵守的規(guī)則等等。
<html lang="zh-CN">
<!-- ... -->
</html>
字符編碼
【強(qiáng)制】通過(guò)聲明一個(gè)明確的字符編碼练对,讓瀏覽器輕松遍蟋、快速的確定網(wǎng)頁(yè)內(nèi)容渲染方式,通常指定為'UTF-8'
<html>
<head>
<meta charset="UTF-8">
</head>
...
引入 CSS 和 JavaScript 文件
【強(qiáng)制】根據(jù) HTML5 規(guī)范螟凭,在引入 CSS 和 JavaScript 文件時(shí)不需要指定 type 屬性虚青,因?yàn)?text/css 和 text/javascript 分別是它們的默認(rèn)值
<!-- 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>
減少標(biāo)簽的數(shù)量
【推薦】編寫 HTML 代碼時(shí),盡量避免多余的層級(jí)
<!-- not good -->
<span class="avatar">
<img src="...">
</span>
<!-- good -->
<img class="avatar" src="...">
屬性順序
【參考】屬性應(yīng)該按照特定的順序出現(xiàn)以保證易讀性
class
id
name
data-*
-
src
,for
,type
,href
,value
,max-length
,max
,min
,pattern
-
placeholder
,title
,alt
-
aria-*
,role
-
required
,readonly
,disabled
語(yǔ)義化
【參考】盡量遵循 HTML 標(biāo)準(zhǔn)和語(yǔ)義螺男,但是不要以犧牲實(shí)用性為代價(jià)棒厘;任何時(shí)候都要盡量使用最少的標(biāo)簽并保持最小的復(fù)雜度。
4.2 CSS / Less 編碼規(guī)范
命名
【強(qiáng)制】類名使用小寫字母下隧,以中劃線分隔
【強(qiáng)制】id 采用駝峰式命名
【強(qiáng)制】less 中的變量奢人、函數(shù)、混合等采用駝峰式命名
@mainFontColor: #444;
#companyName,
.company-name {
color: @mainFontColor;
}
語(yǔ)法
- 【強(qiáng)制】所有聲明語(yǔ)句都應(yīng)當(dāng)以分號(hào)結(jié)尾 最后一條聲明語(yǔ)句后面的分號(hào)是可選的淆院,但是何乎,如果省略這個(gè)分號(hào),你的代碼可能更易出錯(cuò)
/* error */
.selector {
font-size: 15px
color: red
}
/* not good */
.selector {
font-size: 15px;
color: red
}
/* good */
.selector {
font-size: 15px;
color: red;
}
- 【強(qiáng)制】避免為 0 值指定單位土辩,例如支救,用
margin: 0;
代替margin: 0px;
- 【強(qiáng)制】為選擇器中的屬性添加雙引號(hào),例如拷淘,
input[type="text"]
各墨; 某些情況下是可選的,但是启涯,為了代碼的一致性贬堵,建議都加上雙引號(hào)
/* not good */
.selector[type=text] {
/* ... */
}
/* good */
.selector[type="text"] {
/* ... */
}
【強(qiáng)制】十六進(jìn)制值應(yīng)該全部小寫,例如结洼,
#f3f6fa
【強(qiáng)制】不出現(xiàn)空的規(guī)則(聲明塊中沒(méi)有聲明語(yǔ)句)
【強(qiáng)制】不要設(shè)置太大的z-index(一個(gè)正常的系統(tǒng)的層級(jí)關(guān)系在 10 以內(nèi)就能完成)
【強(qiáng)制】多寫注釋黎做,且多使用句子進(jìn)行描述而不是詞語(yǔ)
/* 為了去除輸入框和表單點(diǎn)擊時(shí)的灰色背景 */
input,
form {
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
}
【推薦】不要使用*選擇器
【推薦】適當(dāng)使用
:before
和:after
來(lái)畫(huà)頁(yè)面的一些視覺(jué)上的輔助性元素,如三角形补君、短的分隔線引几、短豎線等,可以減少頁(yè)面上沒(méi)有用的標(biāo)簽【推薦】選擇器不要超過(guò)4層(在 Less 中避免嵌套超過(guò) 4 層)
【推薦】用
border: 0;
代替border: none;
【推薦】使用簡(jiǎn)寫形式的十六進(jìn)制值挽铁,例如伟桅,用
#fff
代替#ffffff
【推薦】對(duì)于屬性值或顏色參數(shù),省略小于 1 的小數(shù)前面的 0 (例如叽掘,
.5
代替0.5
楣铁;-.5px
代替-0.5px
)
代碼風(fēng)格
此處大部分工作將由代碼格式化工具完成(參見(jiàn)環(huán)境要求),一般無(wú)需考慮
- 【強(qiáng)制】縮進(jìn)使用兩個(gè)空格代替 Tab
- 【強(qiáng)制】為選擇器分組時(shí)更扁,將單獨(dú)的選擇器單獨(dú)放在一行
/* not good */
.selector, .selector-secondary, .selector[type=text] {
/* ... */
}
/* good */
.selector,
.selector-secondary,
.selector[type="text"] {
/* ... */
}
【強(qiáng)制】聲明塊的左花括號(hào)前添加一個(gè)空格
【強(qiáng)制】聲明塊的右花括號(hào)應(yīng)當(dāng)單獨(dú)成行
【強(qiáng)制】每條聲明語(yǔ)句的 : 后應(yīng)該插入一個(gè)空格
【強(qiáng)制】每條樣式聲明應(yīng)該獨(dú)占一行
/* not good */
.selector {
font-size: 15px; color: red;
}
/* good */
.selector {
font-size: 15px;
color: red;
}
- 【強(qiáng)制】對(duì)于以逗號(hào)分隔的屬性值盖腕,每個(gè)逗號(hào)后面都應(yīng)該插入一個(gè)空格(例如赫冬,
box-shadow
,transition
)
/* not good */
.selector {
transition: border .2s,color .3s,padding .4s;
}
/* good */
.selector {
transition: border .2s, color .3s, padding .4s;
}
【強(qiáng)制】
!important
前插入一個(gè)空格【強(qiáng)制】注釋:
//
后插入一個(gè)空格溃列,/*
后插入一個(gè)空格劲厌,*/
前插入一個(gè)空格【強(qiáng)制】Less 的操作符,在圓括號(hào)中的數(shù)學(xué)計(jì)算表達(dá)式的數(shù)值听隐、變量和操作符之間均添加一個(gè)空格
【推薦】注釋統(tǒng)一用
/* */
( Less 中也不要用//
)
樣式兼容性
【強(qiáng)制】當(dāng)使用一些較新的 CSS3 語(yǔ)法時(shí)补鼻,應(yīng)注意添加瀏覽器前綴( FAIS 2 打包工具包含 CSS 預(yù)處理,固無(wú)需考慮此條)
【推薦】不要使用 input 的
line-height
來(lái)做垂直居中 設(shè)置line-height
為一個(gè)很高的值會(huì)導(dǎo)致 Safari 瀏覽器的輸入光標(biāo)變得巨大 (與line-height
等高)
/* not good */
input {
height: 40px;
line-height: 40px;
}
/* good */
input {
height: 20px;
line-height: 20px;
padding: 10px 0;
}
選擇器權(quán)重(樣式覆蓋)
權(quán)重的基本規(guī)則:
- 相同的權(quán)重:以后面出現(xiàn)的選擇器為最后規(guī)則
- 相同的權(quán)重:以后面出現(xiàn)的選擇器為最后規(guī)則
詳細(xì)了解權(quán)重計(jì)算方法
- 【強(qiáng)制】非通用樣式使用嵌套方式進(jìn)行編寫雅任,避免影響其他自己不了解樣式风范,造成樣式覆蓋
- 【推薦】Vue 中樣式謹(jǐn)慎使用 scoped,會(huì)影響樣式選擇器性能沪么,請(qǐng)使用第一點(diǎn)進(jìn)行特有樣式編寫
- 【推薦】樣式需要修改時(shí)硼婿,盡量找到原樣式聲明進(jìn)行修改
- 【強(qiáng)制】無(wú)法修改原樣式聲明時(shí),應(yīng)通過(guò)權(quán)重關(guān)系禽车,編寫權(quán)重更高的樣式進(jìn)行覆蓋
- 【強(qiáng)制】不使用
!important
寇漫,除非原樣式使用內(nèi)聯(lián)樣式或!important
且無(wú)法直接修改
聲明簡(jiǎn)寫
- 【推薦】當(dāng)你不確定自己寫的屬性會(huì)否影響到其他屬性時(shí),應(yīng)避免使用簡(jiǎn)寫
/* error */
.element {
margin: 0 0 10px;
background: red;
background: url("image.jpg");
border-radius: 3px 3px 0 0;
}
/* good */
.element {
margin-bottom: 10px;
background-color: red;
background-image: url("image.jpg");
border-top-left-radius: 3px;
border-top-right-radius: 3px;
}
- 【推薦】當(dāng)你確定自己的聲明不會(huì)影響到其他屬性時(shí)哭当,請(qǐng)使用簡(jiǎn)寫提升代碼簡(jiǎn)潔性
/* not good */
.element {
padding-top: 10px;
padding-right: 20px;
padding-bottom: 15px;
padding-left: 20px;
}
/* good */
.element {
padding: 10px 20px 15px;
}
CSS動(dòng)畫(huà)
- 【推薦】不要使用all屬性做動(dòng)畫(huà)
使用transition做動(dòng)畫(huà)的時(shí)候不要使用all所有屬性猪腕,在有一些瀏覽器上面可能會(huì)有一些問(wèn)題,如下:
transition: all 2s linear;
在Safari上面可能會(huì)有一些奇怪的抖動(dòng)钦勘,正確的做法是要用哪個(gè)屬性做動(dòng)畫(huà)就寫哪個(gè),如果有多個(gè)就用隔開(kāi)亚亲,如下代碼所示:
transition: transform 2s linear, opacity 2s linear;
- 【推薦】位移動(dòng)畫(huà)使用 transform 替代 position (提升動(dòng)畫(huà)性能)
- 【推薦】使用 CSS 動(dòng)畫(huà)替代 JS 動(dòng)畫(huà)
聲明順序
【參考】相關(guān)的屬性聲明按以下順序做分組處理彻采,組之間需要有一個(gè)空行
Positioning(影響其他元素和自身位置相關(guān)聲明
Box model(自身盒模型相關(guān)聲明)
Typographic(文本相關(guān)聲明)
Visual(自身樣式)
Misc(其他聲明)
.declaration-order {
/* Positioning */
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 100;
/* Box-model */
display: block;
float: right;
width: 100px;
height: 100px;
/* Typography */
font: normal 13px "Helvetica Neue", sans-serif;
line-height: 1.5;
color: #333;
text-align: center;
/* Visual */
background-color: #f5f5f5;
border: 1px solid #e5e5e5;
border-radius: 3px;
/* Misc */
opacity: 1;
}
4.3 JavaScript 編碼規(guī)范
命名
【強(qiáng)制】標(biāo)準(zhǔn)變量采用駝峰式命名(考慮與后臺(tái)交換數(shù)據(jù)的情況,對(duì)象屬性可靈活命名)
【強(qiáng)制】常量全大寫捌归,用下劃線連接
【強(qiáng)制】變量名不應(yīng)過(guò)短肛响,要能準(zhǔn)確完整地描述該變量所表述的事物
不好的變量名 | 好的變量名 |
---|---|
inp | input, priceInput |
day1, day2, param1 | today, tomorrow |
id | userId, orderId |
obj | orderData, houseInfos |
tId | removeMsgTimerId |
handler | submitHandler, searchHandler |
【強(qiáng)制】變量名不要使用計(jì)算機(jī)術(shù)語(yǔ),如 texareaData惜索,應(yīng)該取和業(yè)務(wù)相關(guān)的名字特笋,如 leaveMsg
【強(qiáng)制】變量名的對(duì)仗要明確,如 up/down巾兆、begin/end猎物、opened/closed、visible/invisible蔫磨、scource/target
【強(qiáng)制】變量名使用正確的語(yǔ)法
不要使用中文拼音,如 shijianchuo 應(yīng)改成 timestamp 圃伶; 如果是復(fù)數(shù)的話加 s堤如,或者加上 List蒲列,如 orderList、menuItems搀罢; 而過(guò)去式的加上 ed蝗岖,如 updated/found 等; 如果正在進(jìn)行的加上 ing榔至,如 calling抵赢;
- 【推薦】使用臨時(shí)變量時(shí)請(qǐng)結(jié)合實(shí)際需要進(jìn)行變量命名
些喜歡取temp和obj之類的變量,如果這種臨時(shí)變量在兩行代碼內(nèi)就用完了洛退,接下來(lái)的代碼就不會(huì)再用了瓣俯,還是可以接受的,如交換數(shù)組的兩個(gè)元素兵怯。但是有些人取了個(gè)temp彩匕,接下來(lái)十幾行代碼都用到了這個(gè)temp,這個(gè)就讓人很困惑了媒区。所以應(yīng)該盡量少用temp類的變量
// not good
let temp = 10;
let leftPosition = currentPosition + temp驼仪,
topPosition = currentPosition - temp;
// good
let adjustSpace = 10;
let leftPosition = currentPosition + adjustSpace,
topPosition = currentPosition - adjustSpace;
- 【推薦】波爾變量可以結(jié)合實(shí)際語(yǔ)境使用 done/found/successs/ok/available/complete 等修飾詞
// good
let ajaxDone = true,
fileFound = false,
resourceUpdated = true;
- 【推薦】波爾變量名應(yīng)使用肯定的布爾變量名袜漩,不要使用否定的名詞绪爸,如 notOk、notReady宙攻,因?yàn)榉穸ǖ脑~取反的時(shí)候就會(huì)比較奇怪奠货,如
if (!notOk)
語(yǔ)法
【強(qiáng)制】變量不要先使用后聲明
【強(qiáng)制】不要聲明了變量卻不使用
【強(qiáng)制】不要在同個(gè)作用域下聲明同名變量
【強(qiáng)制】一個(gè)函數(shù)作用域中所有的變量聲明盡量提到函數(shù)首部,可根據(jù)代碼進(jìn)行分組座掘,但不允許出現(xiàn)兩個(gè)連續(xù)的變量聲明
// not good
let registerForm = null;
let question = "";
let calculateResult = 0;
// good
let registerForm = null,
question = "",
calculateResult = 0;
- 【強(qiáng)制】為了快速知曉變量類型递惋,聲明變量時(shí)要賦值
// not good
let registerForm,
question,
calculateResult;
// good
let registerForm = null,
question = "",
calculateResult = 0;
- 【強(qiáng)制】單一函數(shù)的返回值類型要確定(如下無(wú)法確定該函數(shù)的最終返回類型)
// not good
function calculatePrice(seatCount){
if (seatCount <= 0) {
return "";
} else {
return seatCount * 79;
}
}
【強(qiáng)制】debugger不要出現(xiàn)在提交的代碼里
【推薦】使用
===
代替==
,!==
代替!=
(==
會(huì)自動(dòng)進(jìn)行類型轉(zhuǎn)換溢陪,可能會(huì)出現(xiàn)奇怪的結(jié)果)
null == undefined //true
'' == '0' //false
0 == '' //true
0 == '0' //true
' \t\r\n ' == 0 //true
new String("abc") == "abc" //true
new Boolean(true) == true //true
true == 1 //true
- 【推薦】使用三目運(yùn)算代替簡(jiǎn)單的
if-else
// not good
let seatDiscount = 100;
if (seat < 5) {
seatDiscount = 90;
} else if(seat < 10) {
seatDiscount = 80;
} else {
seatDiscount = 70;
}
// good
let seatDiscount = seat < 5 ? 90 : seat < 10 ? 80 : 70;
【推薦】使用
let
定義變量萍虽,const
定義常量【推薦】使用箭頭函數(shù)取代簡(jiǎn)單的函數(shù)
// not good
let _this = this;
setTimeout(function() {
_this.foo = "bar";
}, 2000);
// good
setTimeout(() => this.foo = "bar", 2000);
【推薦】在必要的地方添加非空判斷以提高代碼的穩(wěn)健性
【推薦】將復(fù)雜的函數(shù)分解成多個(gè)子函數(shù),方便維護(hù)和復(fù)用
代碼風(fēng)格
此處大部分工作將由代碼格式化工具完成(參見(jiàn)環(huán)境要求)形真,一般無(wú)需考慮
【強(qiáng)制】縮進(jìn)使用兩個(gè)空格代替 Tab
【強(qiáng)制】統(tǒng)一使用雙引號(hào)""(與 Prettier 默認(rèn)格式化配置持一致)
-
【強(qiáng)制】以下幾種情況后需加分號(hào);
變量聲明
表達(dá)式
return
throw
break
continue
do-while
-
【強(qiáng)制】以下幾種情況不需要空格:
- 二元運(yùn)算符前后
- 三元運(yùn)算符'?:'前后
- 代碼塊'{'前
- 下列關(guān)鍵字前:
else
,while
,catch
,finally
- 下列關(guān)鍵字后:
if
,else
,for
,while
,do
,switch
,case
,try
,catch
,finally
,with
,
return
,typeof
- 單行注釋'//'后(若單行注釋和代碼同行杉编,則'//'前也需要),多行注釋'*'后
- 對(duì)象的屬性值前
- for循環(huán)咆霜,分號(hào)后留有一個(gè)空格邓馒,前置條件如果有多個(gè),逗號(hào)后留一個(gè)空格
- 無(wú)論是函數(shù)聲明還是函數(shù)表達(dá)式裕便,'{'前一定要有空格
- 函數(shù)的參數(shù)之間
數(shù)組绒净、對(duì)象
1.【強(qiáng)制】對(duì)象屬性名不需要加引號(hào)
2.【強(qiáng)制】對(duì)象以縮進(jìn)的形式書(shū)寫,不要寫在一行
3.【強(qiáng)制】數(shù)組中不要存在空元素
4.【強(qiáng)制】不要用for in循環(huán)數(shù)組
5.【推薦】數(shù)組偿衰、對(duì)象最后不要有逗號(hào)
// not good
let a = {
'b': 1
};
let a = { b: 1 };
let a = {
b: 1,
c: 2,
};
// good
let a = {
b: 1,
c: 2
};
使用 null
【強(qiáng)制】正確使用 null
適用場(chǎng)景:
- 初始化一個(gè)將來(lái)可能被賦值為對(duì)象的變量
- 與已經(jīng)初始化的變量做比較
- 作為一個(gè)參數(shù)為對(duì)象的函數(shù)的調(diào)用傳參
- 作為一個(gè)返回對(duì)象的函數(shù)的返回值
不要用null來(lái)判斷函數(shù)調(diào)用時(shí)有無(wú)傳參
不要與未初始化的變量做比較
// not good
function test(a, b) {
if (b === null) {
// not mean b is not supply
// ...
}
}
let a;
if (a === null) {
// ...
}
// good
let a = null;
if (a === null) {
// ...
}
使用 undefined
【強(qiáng)制】正確使用 undefined
不要給變量賦值 undefined(undefined 本身就表示一個(gè)變量未定義)
不要直接使用 undefined 進(jìn)行變量判斷
使用
typeof
和字符串'undefined'
對(duì)變量進(jìn)行判斷
// not good
if (person === undefined) {
// ...
}
// good
if (typeof person === 'undefined') {
// ...
}
文檔注釋
【參考】各類標(biāo)簽 @param, @method 等請(qǐng)參考 usejsdoc 和 JSDoc Guide挂疆;
建議在以下情況下使用:
- 所有常量
- 所有函數(shù)
- 所有類
/**
* @func
* @desc 一個(gè)帶參數(shù)的函數(shù)
* @param {string} a - 參數(shù)a
* @param {number} b=1 - 參數(shù)b默認(rèn)值為1
* @param {string} c=1 - 參數(shù)c有兩種支持的取值</br>1—表示x</br>2—表示xx
* @param {object} d - 參數(shù)d為一個(gè)對(duì)象
* @param {string} d.e - 參數(shù)d的e屬性
* @param {string} d.f - 參數(shù)d的f屬性
* @param {object[]} g - 參數(shù)g為一個(gè)對(duì)象數(shù)組
* @param {string} g.h - 參數(shù)g數(shù)組中一項(xiàng)的h屬性
* @param {string} g.i - 參數(shù)g數(shù)組中一項(xiàng)的i屬性
* @param {string} [j] - 參數(shù)j是一個(gè)可選參數(shù)
*/
function foo(a, b, c, d, g, j) {
// ...
}
4.4 Vue 組件編碼規(guī)范
命名
- 【強(qiáng)制】組件名應(yīng)該始終是多個(gè)單詞的改览,根組件
App
除外
// not good
Vue.component('todo', {
// ...
})
export default {
name: 'Todo',
// ...
}
// good
Vue.component('todo-item', {
// ...
})
export default {
name: 'TodoItem',
// ...
}
- 【強(qiáng)制】單文件組件的文件名應(yīng)該要么始終是單詞大寫開(kāi)頭( PascalCase ),要么始終是橫線連接( kebab-case )
// not good
components/
|- mycomponent.vue
components/
|- myComponent.vue
// good
components/
|- MyComponent.vue
components/
|- my-component.vue
- 【推薦】應(yīng)用特定樣式和約定的基礎(chǔ)組件 (也就是展示類的缤言、無(wú)邏輯的或無(wú)狀態(tài)的組件) 應(yīng)該全部以一個(gè)特定的前綴開(kāi)頭宝当,比如 Base、App 或 V
// not good
components/
|- MyButton.vue
|- VueTable.vue
|- Icon.vue
// good
components/
|- BaseButton.vue
|- BaseTable.vue
|- BaseIcon.vue
components/
|- AppButton.vue
|- AppTable.vue
|- AppIcon.vue
components/
|- VButton.vue
|- VTable.vue
|- VIcon.vue
- 【推薦】只應(yīng)該擁有單個(gè)活躍實(shí)例的單例組件應(yīng)該以 The 前綴命名胆萧,以示其唯一性
單例組件不意味著組件只可用于一個(gè)單頁(yè)面庆揩,而是每個(gè)頁(yè)面只使用一次。這些組件永遠(yuǎn)不接受任何 prop跌穗,因?yàn)樗鼈兪菫槟愕膽?yīng)用定制的订晌,而不是它們?cè)谀愕膽?yīng)用中的上下文。如果你發(fā)現(xiàn)有必要添加 prop蚌吸,那就表明這實(shí)際上是一個(gè)可復(fù)用的組件锈拨,只是目前在每個(gè)頁(yè)面里只使用一次
// not good
components/
|- Heading.vue
|- MySidebar.vue
// good
components/
|- TheHeading.vue
|- TheSidebar.vue
- 【強(qiáng)制】和父組件緊密耦合的子組件應(yīng)該以父組件名作為前綴命名
如果一個(gè)組件只在某個(gè)父組件的場(chǎng)景下有意義,這層關(guān)系應(yīng)該體現(xiàn)在其名字上羹唠。因?yàn)榫庉嬈魍ǔ?huì)按字母順序組織文件奕枢,所以這樣做可以把相關(guān)聯(lián)的文件排在一起
// not good
components/
|- TodoList.vue
|- TodoItem.vue
|- TodoButton.vue
components/
|- SearchSidebar.vue
|- NavigationForSearchSidebar.vue
//good
components/
|- TodoList.vue
|- TodoListItem.vue
|- TodoListItemButton.vue
components/
|- SearchSidebar.vue
|- SearchSidebarNavigation.vue
- 【強(qiáng)制】組件名應(yīng)該以高級(jí)別的 (通常是一般化描述的) 單詞開(kāi)頭,以描述性的修飾詞結(jié)尾
// not good
components/
|- ClearSearchButton.vue
|- ExcludeFromSearchInput.vue
|- LaunchOnStartupCheckbox.vue
|- RunSearchButton.vue
|- SearchInput.vue
|- TermsCheckbox.vue
// good
components/
|- SearchButtonClear.vue
|- SearchButtonRun.vue
|- SearchInputQuery.vue
|- SearchInputExcludeGlob.vue
|- SettingsCheckboxTerms.vue
|- SettingsCheckboxLaunchOnStartup.vue
- 【推薦】組件名應(yīng)該傾向于完整單詞而不是縮寫
// not good
components/
|- SdSettings.vue
|- UProfOpts.vue
// good
components/
|- StudentDashboardSettings.vue
|- UserProfileOptions.vue
語(yǔ)法
- 【強(qiáng)制】組件的
data
必須是一個(gè)函數(shù)(除了new Vue
外的任何地方)
// not good
export default {
data: {
foo: 'bar'
}
}
// good
export default {
data () {
return {
foo: 'bar'
}
}
}
- 【強(qiáng)制】
prop
的定義應(yīng)該盡量詳細(xì)佩微,至少需要指定其類型
// not good
// 這樣做只有開(kāi)發(fā)原型系統(tǒng)時(shí)可以接受
props: ['status']
// good
props: {
status: String
}
// better
props: {
status: {
type: String,
required: true,
validator: function (value) {
return [
'syncing',
'synced',
'version-conflict',
'error'
].indexOf(value) !== -1
}
}
}
- 【強(qiáng)制】為
v-for
設(shè)置鍵值缝彬;在組件上總是必須用key
配合v-for
,以便維護(hù)內(nèi)部組件及其子樹(shù)的狀態(tài)在組件上總是必須用key
配合v-for
哺眯,以便維護(hù)內(nèi)部組件及其子樹(shù)的狀態(tài)
4.【強(qiáng)制】不要把 v-if
和 v-for
同時(shí)用在同一個(gè)元素上(大部分時(shí)候你可以使用計(jì)算屬性實(shí)現(xiàn))
<!-- not good -->
<ul>
<li
v-for="user in users"
v-if="user.isActive"
:key="user.id"
>
{{ user.name }}
</li>
</ul>
<!-- good -->
<ul>
<li
v-for="user in activeUsers"
:key="user.id"
>
{{ user.name }}
</li>
</ul>
- 【強(qiáng)制】自閉合組件在單文件組件谷浅、字符串模板和 JSX 中沒(méi)有內(nèi)容的組件應(yīng)該是自閉合的;但在 DOM 模板里不要這樣做
<!-- not good -->
<!-- 在單文件組件奶卓、字符串模板和 JSX 中 -->
<MyComponent></MyComponent>
<!-- 在 DOM 模板中 -->
<my-component/>
<!-- good -->
<!-- 在單文件組件壳贪、字符串模板和 JSX 中 -->
<MyComponent/>
<!-- 在 DOM 模板中 -->
<my-component></my-component>
- 【強(qiáng)制】模版中的組件名大小寫在單文件組件和字符串模板中組件名應(yīng)該總是 PascalCase 的;但是在 DOM 模板中總是 kebab-case 的
<!-- not good -->
<!-- 在單文件組件和字符串模板中 -->
<mycomponent/>
<!-- 在單文件組件和字符串模板中 -->
<myComponent/>
<!-- 在 DOM 模板中 -->
<MyComponent></MyComponent>
<!-- good -->
<!-- 在單文件組件和字符串模板中 -->
<MyComponent/>
<!-- 在 DOM 模板中 -->
<my-component></my-component>
亦或者
<!-- 在所有地方 -->
<my-component></my-component>
- 【強(qiáng)制】JS/JSX 中的組件名應(yīng)該始終是 PascalCase 的
// not good
Vue.component('myComponent', {
// ...
})
import myComponent from './MyComponent.vue'
export default {
name: 'myComponent',
// ...
}
export default {
name: 'my-component',
// ...
}
// good
Vue.component('MyComponent', {
// ...
})
import MyComponent from './MyComponent.vue'
export default {
name: 'MyComponent',
// ...
}
- 【推薦】Prop 名大小寫寝杖,在聲明 prop 的時(shí)候,其命名應(yīng)該始終使用 camelCase互纯,而在模板和 JSX 中應(yīng)該始終使用 kebab-case
// not good
props: {
'greeting-text': String
}
<WelcomeMessage greetingText="hi"/>
// good
props: {
greetingText: String
}
<WelcomeMessage greeting-text="hi"/>
- 【推薦】多個(gè)特性的元素應(yīng)該分多行撰寫瑟幕,每個(gè)特性一行(此項(xiàng) Vetur 插件會(huì)自動(dòng)根據(jù)行寬閾值進(jìn)行自動(dòng)折行處理,一般無(wú)需考慮)
<!-- not good -->
<img src="https://vuejs.org/images/logo.png" alt="Vue Logo">
<MyComponent foo="a" bar="b" baz="c"/>
<!-- good -->
<img
src="https://vuejs.org/images/logo.png"
alt="Vue Logo"
>
<MyComponent
foo="a"
bar="b"
baz="c"
/>
- 【強(qiáng)制】組件模板應(yīng)該只包含簡(jiǎn)單的表達(dá)式留潦,復(fù)雜的表達(dá)式則應(yīng)該重構(gòu)為計(jì)算屬性或方法
// not good
{{
fullName.split(' ').map(function (word) {
return word[0].toUpperCase() + word.slice(1)
}).join(' ')
}}
// good
// 在模板中
{{ normalizedFullName }}
// 復(fù)雜表達(dá)式已經(jīng)移入一個(gè)計(jì)算屬性
computed: {
normalizedFullName: function () {
return this.fullName.split(' ').map(function (word) {
return word[0].toUpperCase() + word.slice(1)
}).join(' ')
}
}
- 【推薦】應(yīng)該把復(fù)雜計(jì)算屬性分割為盡可能多的更簡(jiǎn)單的屬性
// not good
computed: {
finalPrice: function () {
var basePrice = this.manufactureCost / (1 - this.profitMargin)
return (
basePrice -
basePrice * (this.discountPercent || 0)
)
}
}
// good
computed: {
basePrice: function () {
return this.manufactureCost / (1 - this.profitMargin)
},
discount: function () {
return this.basePrice * (this.discountPercent || 0)
},
finalPrice: function () {
return this.basePrice - this.discount
}
}
- 【強(qiáng)制】非空 HTML 特性值應(yīng)該始終帶引號(hào)
<!-- not good -->
<input type=text>
<AppSidebar :style={width:sidebarWidth+'px'}>
<!-- good -->
<input type="text">
<AppSidebar :style="{ width: sidebarWidth + 'px' }">
- 【強(qiáng)制】可簡(jiǎn)寫指令需要縮寫 (用
:
表示v-bind:
和用@
表示v-on:
)
代碼風(fēng)格
此處大部分工作將由代碼格式化工具完成(參見(jiàn)環(huán)境要求)狭姨,一般無(wú)需考慮
具體要求見(jiàn) 4.1 胁塞,4.2,4.3 中代碼風(fēng)格部分
組件/實(shí)例的選項(xiàng)的順序
【參考】組件/實(shí)例的選項(xiàng)應(yīng)該有統(tǒng)一的順序,這是我們推薦的組件選項(xiàng)默認(rèn)順序:
-
副作用 (觸發(fā)組件外的影響)
el
-
全局感知 (要求組件以外的知識(shí))
name
parent
-
組件類型 (更改組件的類型)
functional
-
模板修改器 (改變模板的編譯方式)
delimiters
comments
-
模板依賴 (模板內(nèi)使用的資源)
components
directives
filters
-
組合 (向選項(xiàng)里合并屬性)
extends
mixins
-
接口 (組件的接口)
inheritAttrs
model
props/propsData
-
本地狀態(tài) (本地的響應(yīng)式屬性)
- data
- computed
-
事件 (通過(guò)響應(yīng)式事件觸發(fā)的回調(diào))
- watch
- 生命周期鉤子 (按照它們被調(diào)用的順序)
beforeCreate
created
beforeMount
mounted
beforeUpdate
updated
activated
deactivated
beforeDestroy
destroyed
-
非響應(yīng)式的屬性 (不依賴響應(yīng)系統(tǒng)的實(shí)例屬性)
- methods
-
渲染 (不依賴響應(yīng)系統(tǒng)的實(shí)例屬性)
-
template
/
render
renderError
-
元素特性的順序
【參考】元素 (包括組件) 的特性應(yīng)該有統(tǒng)一的順序色洞,這是我們?yōu)樵靥匦酝扑]的默認(rèn)順序
-
定義 (提供組件的選項(xiàng))
is
-
列表渲染 (創(chuàng)建多個(gè)變化的相同元素)
v-for
- **條件渲染 **(元素是否渲染/顯示)
v-if
v-else-if
v-else
v-show
v-cloak
-
渲染方式 (改變?cè)氐匿秩痉绞?
v-pre
v-once
-
全局感知 (需要超越組件的知識(shí))
id
-
唯一的特性 (需要唯一值的特性)
ref
key
slot
-
雙向綁定 (把綁定和事件結(jié)合起來(lái))
v-model
- 其它特性 (所有普通的綁定或未綁定的特性)
-
事件 (組件事件監(jiān)聽(tīng)器)
v-on
- 內(nèi)容 (覆寫元素的內(nèi)容)
v-html
v-text
單文件組件的頂級(jí)元素的順序
【強(qiáng)制】單文件組件應(yīng)該總是按照 <template>
、<script>
和 <style>
的標(biāo)簽順序
<!-- good -->
<!-- ComponentA.vue -->
<template>...</template>
<style>/* ... */</style>
<!-- ComponentB.vue -->
<template>...</template>
<script>/* ... */</script>
<style>/* ... */</style>
隱性的父子組件通信
【強(qiáng)制】應(yīng)該優(yōu)先通過(guò) prop 和事件進(jìn)行父子組件之間的通信隶症,而不是 this.$parent 或改變 prop。
一個(gè)理想的 Vue 應(yīng)用是 prop 向下傳遞许起,事件向上傳遞的。遵循這一約定會(huì)讓你的組件更易于理解菩鲜。然而园细,在一些邊界情況下 prop 的變更或this.$parent
能夠簡(jiǎn)化兩個(gè)深度耦合的組件。
問(wèn)題在于接校,這種做法在很多簡(jiǎn)單的場(chǎng)景下可能會(huì)更方便猛频。但請(qǐng)當(dāng)心,不要為了一時(shí)方便 (少寫代碼) 而犧牲數(shù)據(jù)流向的簡(jiǎn)潔性 (易于理解)蛛勉。
非 Flux 的全局狀態(tài)管理
【強(qiáng)制】應(yīng)該優(yōu)先通過(guò) Vuex 管理全局狀態(tài)鹿寻,而不是通過(guò) this.$root 或一個(gè)全局事件總線。
通過(guò) this.$root
和/或全局事件總線管理狀態(tài)在很多簡(jiǎn)單的情況下都是很方便的诽凌,但是并不適用于絕大多數(shù)的應(yīng)用毡熏。Vuex 提供的不僅是一個(gè)管理狀態(tài)的中心區(qū)域,還是組織皿淋、追蹤和調(diào)試狀態(tài)變更的好工具招刹。