前端開發規范基礎匯總
命名規范
常用的命名規范
- camelCase(小駝峰式命名法 —— 首字小寫)
- PascalCase(大駝峰式命名法 —— 首字大寫)
- snake_case(下劃線命名法)
- kebab-case(短橫線命名法)
項目文件命名
項目命名
全部采用小寫方式,以短橫線分隔。例:my-project-name
。
- 全部小寫,單詞之間用中劃線隔開
- 不能以數字開頭
- 不能包含特殊字符(除了中劃線)
目錄命名
參照項目命名規則,有復數結構時,要采用復數命名法。例:docs
、assets
、components
、directives
、mixins
、utils
、views
。
圖像文件命名
全部采用小寫方式,優先選擇單個單詞命名,多單詞名以短橫線分隔。例:my-image-name.png
。
banner_sina.gif
menu_aboutus.gif
menutitle_news.gif
logo_police.gif
logo_national.gif
pic_people.jpg
pic_TV.jpg
HTML 文件命名
全部采用小寫方式,優先選擇單個單詞命名,多單詞名以短橫線分隔。例:my-html-name.html
。
error_report.html
success_report.html
CSS 文件命名
全部采用小寫方式,優先選擇單個單詞命名,多單詞名以短橫線分隔。例:my-css-name.css
。
normalize.less
base.less
date-picker.scss
input-number.scss
JavaScript 文件命名
全部采用小寫方式,優先選擇單個單詞命名,多單詞名以短橫線分隔。例:my-js-name.js
。
app.js
utils.js
date-util.js
collapse-transition.js
Vue 組件命名
單文件組件名
文件擴展名為.vue
的單文件。組件名應該始終是單詞大寫開頭 (PascalCase)。
components/
|- MyComponent.vue
單例組件名
只擁有單個活躍實例的組件應該以 The 前綴命名,以示其唯一性。
這不意味著組件只可用于一個單頁面,而是每個頁面只使用一次。這些組件永遠不接受任何 prop
,因為它們是為你的應用定制的。如果你發現有必要添加 prop
,那就表明這實際上是一個可復用的組件,只是目前在每個頁面里只使用一次。
比如,頭部
和側邊欄
組件幾乎在每個頁面都會使用,不接受prop
,該組件是專門為該應用所定制的。
components/
|- TheHeader.vue
|- TheSidebar.vue
基礎組件名
不包含業務,獨立、具體功能的基礎組件.
比如日期選擇器
、模態框
等。這類組件作為項目的基礎控件,會被大量使用,因此組件的API
進行過高強度的抽象,可以通過不同配置實現不同的功能。
應用特定樣式和約定
的基礎組件(也就是展示類的、無邏輯的或無狀態、不摻雜業務邏輯的組件) 應該全部以一個特定的前綴開頭 —— Base
。基礎組件在一個頁面內可使用多次,在不同頁面內也可復用,是高可復用組件。
components/
|- BaseButton.vue
|- BaseTable.vue
|- BaseIcon.vue
業務組件
它不像基礎組件只包含某個功能,而是在業務中被多個頁面復用的(具有可復用性),它與基礎組件的區別是,業務組件只在當前項目中會用到,不具有通用性,而且會包含一些業務,比如數據請求;而基礎組件不含業務,在任何項目中都可以使用,功能單一,比如一個具有數據校驗功能的輸入框。
摻雜了復雜業務的組件(擁有自身 data、prop 的相關處理)即業務組件應該以Custom
前綴命名。業務組件在一個頁面內比如:某個頁面內有一個卡片列表,而樣式和邏輯跟業務緊密相關的卡片就是業務組件。
components/
|- CustomCard.vue
緊密耦合的組件名
和父組件緊密耦合的子組件應該以父組件名作為前綴命名
。 因為編輯器通常會按字母順序組織文件,所以這樣做可以把相關聯的文件排在一起。
components/
|- TodoList.vue
|- TodoListItem.vue
|- TodoListItemButton.vue
組件名中單詞順序
組件名應該以高級別的 (通常是一般化描述的) 單詞開頭,以描述性的修飾詞結尾。 因為編輯器通常會按字母順序組織文件,所以現在組件之間的重要關系一目了然。如下組件主要是用于搜索和設置功能。
components/
|- SearchButtonClear.vue
|- SearchButtonRun.vue
|- SearchInputQuery.vue
|- SearchInputExcludeGlob.vue
|- SettingsCheckboxTerms.vue
|- SettingsCheckboxLaunchOnStartup.vue
還有另一種多級目錄的方式,把所有的搜索組件放到“search”目錄,把所有的設置組件放到“settings”目錄。
完整單詞的組件名
組件名應該傾向于完整單詞而不是縮寫。編輯器中的自動補全已經讓書寫長命名的代價非常之低了,而其帶來的明確性卻是非常寶貴的。不常用的縮寫尤其應該避免。
components/
|- StudentDashboardSettings.vue
|- UserProfileOptions.vue
變量和方法
變量命名
變量命名方法應遵循camelCase
(小駝峰式命名法)。命名規范遵循:類型 + 對象描述或屬性的方式
// bad
var getTitle = "LoginTable"// good
let tableTitle = "LoginTable"
let mySchool = "我的學校"
常量命名
常量命名方法應遵循全部大寫下劃線分割
。命名規范遵循:使用大寫字母和下劃線來組合命名,下劃線用以分割單詞。
const MAX_COUNT = 10
const URL = 'http://test.host.com'
方法命名
方法命名方法應遵循camelCase
(小駝峰式命名法)。命名規范遵循:動詞
或者 動詞 + 名詞
的方式。
// 1、普通情況下,使用動詞 + 名詞形式
// bad
go、nextPage、show、open、login// good
jumpPage、openCarInfoDialog// 2、請求數據方法,以 data 結尾
// bad
takeData、confirmData、getList、postForm// good
getListData、postFormData// 3、單個動詞的情況
init、refresh
動詞 | 含義 | 返回值 |
---|---|---|
can | 判斷是否可執行某個動作 (權 ) | 函數返回一個布爾值。true:可執行;false:不可執行; |
has | 判斷是否含有某個值 | 函數返回一個布爾值。true:含有此值;false:不含有此值; |
is | 判斷是否為某個值 | 函數返回一個布爾值。true:為某個值;false:不為某個值; |
get | 獲取某個值 | 函數返回一個非布爾值 |
set | 設置某個值 | 無返回值、返回是否設置成功或者返回鏈式對象 |
自定義事件
自定義事件應始終使用 kebab-case
的事件名,事件名應全部小寫,且使用短橫線命名。
this.$emit('my-event')<MyComponent @my-event="handleDoSomething" />
- 原生事件參考列表
<div@blur="toggleHeaderBlur"@focus="toggleHeaderFocus"@click="toggleMenu"@keydown.esc="handleKeydown"@keydown.enter="handleKeydown"@keydown.up.prevent="handleKeydown"@keydown.down.prevent="handleKeydown"@keydown.tab="handleKeydown"@keydown.delete="handleKeydown"@mouseenter="hasMouseHoverHead = true"@mouseleave="hasMouseHoverHead = false">
</div>
而為了區分原生事件和自定義事件在 Vue 中的使用,建議除了多單詞事件名使用 kebab-case 的情況下,命名還需遵守為 on + 動詞
的形式,如下:
<!-- 父組件 -->
<div@on-search="handleSearch"@on-clear="handleClear"@on-clickoutside="handleClickOutside">
</div>// 子組件
export default {methods: {handleTriggerItem () {this.$emit('on-clear')}}
}
事件方法
事件方法命名應遵循camelCase
(小駝峰式命名法)。命名規范遵循:handle + 名稱(可選)+ 動詞
的方式。
<div@click.native.stop="handleItemClick()"@mouseenter.native.stop="handleItemHover()">
</div>export default {methods: {handleItemClick () {// 業務邏輯...},handleItemHover () {// 業務邏輯...}}
}
編碼規范
HTML/Template 編碼規范
語法
1. 縮進使用兩個空格代替 Tab
- 前端代碼層級較深,使用短縮進有利于利用屏幕空間,提升效率。
- 使用兩個空格代替 Tab 可以保證在所有環境下獲得一致展現。
<!-- not good -->
<div><div>bar</div>
</div><!-- good -->
<div><div>bar</div>
</div>
2. 嵌套元素應當縮進一次(即兩個空格),同層級縮進應保持一致
<!-- not good -->
<div>
<div>bar</div><div>bar</div>
</div><!-- good -->
<div><div>bar</div><div>bar</div>
</div>
3. 對于屬性的定義,使用雙引號,不要使用單引號
<!-- not good -->
<input class='a' type=text><!-- good -->
<input class="a" type="text">
4. 不要省略可選的結束標簽(closing tag)(如 或 )
<!-- not good -->
<h1>h1 text<h2>h2 text<!-- good -->
<h1>h1 text</h1>
<h2>h2 text</h2>
5. 特殊符號使用 HTML 字符實體(實體名稱對大小寫敏感),常用如下:
符號 | 實體編碼 |
---|---|
空格 | |
? | © |
¥ | ¥ |
? | ® |
> | > |
< | < |
& | & |
6. td / th 要在 tr 里面,li 要在 ul / ol 里面
<!-- not good -->
<table><td>test</td>
</table><!-- good -->
<table><tr><td>test</td></tr>
</table>
7. ul / ol 的直接子元素只能是 li,不能包含其他元素
<!-- not good -->
<ul><span>123</span><li>a</li><li>b</li>
</ul>
8. 行內元素里面不可使用塊級元素
a 標簽是一個行內元素,行內元素里面套了一個 div 的標簽,這樣可能會導致 a 標簽無法正常點擊。
<!-- not good -->
<a href="../test"><div></div>
</a>
可以使用如下代碼進行修復:
<a href="../test" style="display: block"><div></div>
</a>
9. 不使用重復屬性,重復的屬性只會取第一個
<!-- error -->
<input class="a" type="text" class="b"><!-- good -->
<input class="a b" type="text">
10. 不要在自閉合(self-closing)元素的尾部添加斜線( HTML5 規范中說明這是可選的)
<!-- not good -->
<img src="logo.png" alt /><!-- good -->
<img src="logo.png" alt>
11. 盡量不使用屬性設置樣式(img, table等元素)
<!-- not good -->
<img src="test.jpg" alt width="400" height="300"><!-- good -->
<img src="test.jpg" style="width:400px;height:300px;">
11.自定義屬性要以data-開頭 自己添加的非標準的屬性要以data-開頭,否則w3c validator會認為是不規范的
<!-- not good -->
<div count="5"></div><!-- good -->
<div data-count="5"></div>
HTML5 doctype
為每個 HTML 頁面添加標準模式(standard mode)的聲明,確保在每個瀏覽器中擁有一致的展現。
<!DOCTYPE html><html>...
語言屬性
為每個 HTML 頁面根元素添加 lang 屬性。
根據 HTML5 規范:
強烈建議為 html 根元素指定 lang 屬性,從而為文檔設置正確的語言。這將有助于語音合成工具確定其所應該采用的發音,有助于翻譯工具確定其翻譯時所應遵守的規則等等。
<html lang="zh-CN"><!-- ... -->
</html>
字符編碼
通過聲明一個明確的字符編碼,讓瀏覽器輕松、快速的確定網頁內容渲染方式,通常指定為’UTF-8’
<html><head><meta charset="UTF-8"></head>...
引入CSS和JavaScript文件
根據 HTML5 規范,在引入 CSS 和 JavaScript 文件時不需要指定 type 屬性,因為 text/css 和 text/javascript 分別是它們的默認值。
<!-- 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>
減少標簽的數量
建議編寫 HTML 代碼時,條件滿足的情況下盡量避免多余的層級。
<!-- not good -->
<span class="avatar"><img src="...">
</span><!-- good -->
<img class="avatar" src="...">
屬性順序
僅做參考:屬性應該按照特定的順序出現以保證易讀性。
1. class
2. id
3. name
4. data-*
5. src, for, type, href, value , max-length, max, 7. min, pattern
8. placeholder, title, alt
9. aria-*, role
10. required, readonly, disabled
語義化
盡量遵循 HTML 標準和語義,但是不要以犧牲實用性為代價;任何時候都要盡量使用最少的標簽并保持最小的復雜度。
CSS/Less編碼規范
命名
1. 類名使用小寫字母,以中劃線分隔
<div class="user-info"><div class="user-info-name"><span>張三</span></div>
</div>
2. id 采用駝峰式命名
<div id="userInfo"><div class="user-info-name"><span>張三</span></div>
</div>
3. less 中的變量、函數、混合等采用駝峰式命名
@mainFontColor: #444;#companyName,
.company-name {color: @mainFontColor;
}
語法
1. 所有聲明語句都應當以分號結尾
最后一條聲明語句后面的分號是可選的,但是,如果省略這個分號,你的代碼可能更易出錯
/* error */
.selector {font-size: 15pxcolor: red
}/* not good */
.selector {font-size: 15px;color: red
}/* good */
.selector {font-size: 15px;color: red;
}
2. 避免為 0 值指定單位
例如:用 margin: 0; 代替 margin: 0px;
/* not good */
.selector {margin: 0px;
}/* good */
.selector {margin: 0;
}
3. 為選擇器中的屬性添加雙引號,例如,input[type=“text”];
某些情況下是可選的,但是,為了代碼的一致性,建議都加上雙引號。
/* not good */
.selector[type=text] {/* ... */
}/* good */
.selector[type="text"] {/* ... */
}
4. 十六進制值應該全部小寫
例如,#f3f6fa 而不是 #F3F6FA
/* not good */
.selector {color: #F3F6FA;
}/* good */
.selector {color: #f3f6fa;
}
5. 不出現空的規則(聲明塊中沒有聲明語句)
/* not good */
.selector {
}/* good */
.selector {color: #f3f6fa;
}
6. 不要設置太大的z-index
一個正常的系統的層級關系在 10 以內就能完成。
/* not good */
.selector {z-index: 9999;
}/* good */
.selector {z-index: 10;
}
7. 多寫注釋,且多使用句子進行描述而不是詞語
/* 為了去除輸入框和表單點擊時的灰色背景 */
input,
form {-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
}
8. 非特殊情況下,不要使用*選擇器
9. 適當使用:before和:after來畫頁面的一些視覺上的輔助性元素,如三角形、短的分隔線、短豎線等,可以減少頁面上沒有用的標簽
10. 選擇器不要超過4層(在 Less 中避免嵌套超過 4 層)
11. 用 border: 0; 代替 border: none;
/* not good */
.selector {border: none;
}/* good */
.selector {border: 0;
}
12. 使用簡寫形式的十六進制值
例如:用 #fff
代替 #ffffff
。
13. 對于屬性值或顏色參數,省略小于 1 的小數前面的 0
例如:.5
代替 0.5
;-.5px
代替 -0.5px
選擇器權重
權重判斷基本規則:
- 相同的權重:以后面出現的選擇器為最后規則;
- 不同的權重,權重值高則生效;
設置規范:
- 非通用樣式使用嵌套方式進行編寫,避免影響其他自己不了解樣式,造成樣式覆蓋;
- Vue 中樣式合理使用
scoped
,會影響樣式選擇器性能,請使用第一點進行特有樣式編寫; - 樣式需要修改時,盡量找到原樣式聲明進行修改;
- 無法修改原樣式聲明時,應通過權重關系,編寫權重更高的樣式進行覆蓋;
- 不使用
!important
,除非原樣式使用內聯樣式或!important
且無法直接修改;
聲明簡寫
1. 當你不確定自己寫的屬性會否影響到其他屬性時,應避免使用簡寫
/* 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;
}
2. 當你確定自己的聲明不會影響到其他屬性時,請使用簡寫提升代碼簡潔性
/* not good */
.element {padding-top: 10px;padding-right: 20px;padding-bottom: 15px;padding-left: 20px;
}/* good */
.element {padding: 10px 20px 15px;
}
JavaScript編碼規范
命名
1. 標準變量采用駝峰式命名
考慮與后臺交換數據的情況,對象屬性可靈活命名。
let userName = '張三';
let userAge = 18;
2.常量全大寫,用下劃線連接
const USER_NAME = '張三';
const USER_AGE = 18;
3. 變量名并非越短越好
變量名不應過短,要能準確完整地描述該變量所表述的事物。
不好的變量名 | 好的變量名 |
---|---|
inp | input, priceInput |
day1, day2, param1 | today, tomorrow |
id | userId, orderId |
obj | orderData, houseInfos |
tId | removeMsgTimerId |
handler | submitHandler, searchHandler |
4. 變量名不要使用計算機術語
如texareaData
,應該取和業務相關的名字,如 leaveMsg
。
5. 變量名的對仗要明確
如 up/down
、begin/end
、opened/closed
、visible/invisible
、scource/target
。
6. 變量名使用正確的語法
不要使用中文拼音,如 shijianchuo
應改成 timestamp
; 如果是復數的話加 s
,或者加上 List
,如 orderList
、menuItems
; 而過去式的加上 ed
,如 updated/found
等; 如果正在進行的加上 ing
,如 calling
;
7.使用臨時變量時請結合實際需要進行變量命名
有些喜歡取temp
和obj
之類的變量,如果這種臨時變量在兩行代碼內就用完了,接下來的代碼就不會再用了,還是可以接受的,如交換數組的兩個元素。但是有些人取了個temp
,接下來十幾行代碼都用到了這個temp
,這個就讓人很困惑了。所以應該盡量少用temp
類的變量。
// not good
let temp = 10;
let leftPosition = currentPosition + temp,topPosition = currentPosition - temp;// good
let adjustSpace = 10;
let leftPosition = currentPosition + adjustSpace,topPosition = currentPosition - adjustSpace;
語法
1. 變量不要先使用后聲明
a = 10;
let a;
2. 不要聲明了變量卻不使用
let a = 10;
let b;
a = 15;
3. 不要在同個作用域下聲明同名變量
let a = 10;
let a = 15;
4. 一個函數作用域中所有的變量聲明盡量提到函數首部,可根據代碼進行分組,但不允許出現兩個連續的變量聲明
// not good
let registerForm = null;
let question = "";
let calculateResult = 0;// good
let registerForm = null,question = "",calculateResult = 0;
5. 為了快速知曉變量類型,聲明變量時要賦值
// not good
let registerForm,question,calculateResult;// good
let registerForm = null,question = "",calculateResult = 0;
6. 單一函數的返回值類型要確定
如下無法確定該函數的最終返回類型:
// not good
function calculatePrice(seatCount){if (seatCount <= 0) {return "";} else {return seatCount * 79;}
}
7. 建議使用===
代替==
,!==
代替!=
==
會自動進行類型轉換,可能會出現奇怪的結果。
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
8. 使用三目運算代替簡單的 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;
9. 使用let定義變量,const定義常量
let userName = '張三';
const USER_NAME = '張三';
10. 使用箭頭函數取代簡單的函數
// not good
let _this = this;
setTimeout(function() {_this.foo = "bar";
}, 2000);// good
setTimeout(() => this.foo = "bar", 2000);
11. 建議在必要的地方添加非空判斷以提高代碼的穩健性
12. 建議將復雜的函數分解成多個子函數,方便維護和復用
代碼風格
該部分一般采用代碼格式化工具進行統一維護,不再表述。