未經允許不得轉載
夥伴行前端開發手冊
夥伴行研發中心前端組 編
目錄
一、 Airbnb...................................................................................... 6
(一) JavaScript 編碼規範............................................................................. 6
1. 類型........................................................................................................................................................ 6
2. 引用........................................................................................................................................................ 6
3. 對象........................................................................................................................................................ 6
4. 數組........................................................................................................................................................ 9
5. 解構...................................................................................................................................................... 10
6. 字符串................................................................................................................................................ 11
7. 函數...................................................................................................................................................... 11
8. 箭頭函數........................................................................................................................................... 13
9. 構造函數........................................................................................................................................... 14
10. 模塊................................................................................................................................................. 16
11. 迭代器和選擇器........................................................................................................................ 16
12. 屬性................................................................................................................................................. 17
13. 變量................................................................................................................................................. 18
14. 提升................................................................................................................................................. 18
15. 比較運算符和等號.................................................................................................................. 20
16. 代碼塊............................................................................................................................................ 22
17. 註釋................................................................................................................................................. 23
18. 空白................................................................................................................................................. 23
19. 逗號................................................................................................................................................. 24
20. 分號................................................................................................................................................. 25
21. 類型轉換....................................................................................................................................... 26
22. 命名規則....................................................................................................................................... 27
23. 存取器............................................................................................................................................ 28
24. 事件................................................................................................................................................. 29
25. jQuery........................................................................................................................................... 29
(二) HTML 編碼規範.................................................................................... 30
1. 文檔規範........................................................................................................................................... 30
2. 腳本加載........................................................................................................................................... 30
3. 語義化................................................................................................................................................ 32
4. alt 標籤不爲空............................................................................................................................... 32
5. 結構、表現、行爲三者分離................................................................................................... 32
6. HTML 只關注內容...................................................................................................................... 33
7. 屬性順序........................................................................................................................................... 33
1. ID 選擇器......................................................................................................................................... 33
2. JavaScript 鉤子............................................................................................................................ 33
3. 使用子選擇器................................................................................................................................. 34
4. 儘量使用縮寫屬性....................................................................................................................... 34
5. 0 後面不帶單位............................................................................................................................ 34
6. 屬性格式........................................................................................................................................... 35
7. 屬性聲明順序................................................................................................................................. 36
8. 註釋...................................................................................................................................................... 38
9. Sass 屬性聲明的排序................................................................................................................ 38
二、 React/JSX 編碼規範................................................................. 40
1. 基本規範........................................................................................................................................... 40
2. 創建組件的三種方式.................................................................................................................. 40
3. Mixins................................................................................................................................................. 41
4. 命名...................................................................................................................................................... 41
5. 聲明組件:...................................................................................................................................... 43
6. 代碼縮進:...................................................................................................................................... 43
7. 使用雙引號:................................................................................................................................. 44
8. 空格:................................................................................................................................................ 44
9. 屬性:................................................................................................................................................ 44
10. Refs................................................................................................................................................. 48
11. 括號................................................................................................................................................. 49
12. 標籤................................................................................................................................................. 50
13. 函數/方法:................................................................................................................................ 51
14. 組件生命週期書寫順序........................................................................................................ 54
15. isMounted.................................................................................................................................. 54
三、 Ant Design Pro 使用規範........................................................ 55
(一)effects 命名規範....................................................................................................................... 55
1. 使用 submit 開頭提交表單信息。.................................................................................... 55
2. 使用 fetch 開頭獲取數據。.................................................................................................... 55
3. 加載(Loading)命名。.................................................................................................................. 55
4. 使用 save 開頭保存數據。...................................................................................................... 55
1. 使用過程中儘量避免複雜的值操作,值操作可通過在 service 添加 async 方法來轉化或者使用 factory 類進行轉換。.......................................................................................................................... 55
1. 小於 3 個 css 屬性可以直接使用 style。...................................................................... 56
2. 大於等於 3 個屬性必須先到 less 文件中。................................................................... 56
1. Select 篩選建議:........................................................................................................................ 56
2. 數據驗證標準化:......................................................................................................................... 56
3. FileUpload 規範化....................................................................................................................... 56
4. 對於刪除這類的操作必須給予提示(Popconfirm )............................................ 57
四、 開發流程規範............................................................................ 58
以數據爲始,以頁面爲終....................................................................................................................... 58
五、 測試規範.................................................................................. 58
一、 Airbnb
(一) JavaScript 編碼規範
1. 類型
a. 【參考】基本類型:直接存取的類型。如:字符串、數值、布爾類型、null、
undefined。
b. 【參考】複製類型:通過引用的方式存取複雜類型。如:數組、對象、函數。
2. 引用
a. 【推薦】 對所有的引用使用 const ;避免使用 var。(這能確保你無法對引用重新賦值,也不會導致出現bug 或難以理解)
b. 【推薦】如果你一定需要可變動的引用,使用 let 代替 var。正例:let count= 1; if (true) {count += 1;
反例:var count = 1; if (true) {count += 1; }
c. 【參考】注意 let 和 const 都是塊級作用域,const 和 let 只存在於它們被定義的區塊內。
3. 對象
a. 【推薦】請使用字面值創建對象。正例:const item = {};
反例:const item = new Object();
b. 【強制】如果你的代碼在瀏覽器環境下執行,別使用保留字 作爲鍵
值,這樣的話在 IE8 不會運行。但在 ES6 模塊和服務器端中使用沒有問題。
c. 【強制】使用同義詞替換需要使用的保留字。
d. 【推薦】創建有動態屬性名的對象時,使用可被計算的屬性名稱。function getKey(k) {
return `a keynamed ${k}`;
}
正例:
const obj = { id: 5,
name: 'San Francisco', obj[getKey('enabled')] = true;
}
反例:
const obj = { id: 5,
name: 'SanFrancisco',
}
obj[getKey('enabled')]= true;
e. 【推薦】使用對象方法的簡寫。正例:
addValue(value) {
returnatom.value + value;
}
反例:
addValue: function (value) { return atom.value + value;
}
f. 【推薦】使用對象屬性值的簡寫。說明:因爲這樣更短更有描述性。
const lukeSkywalker = 'Luke Skywalker'; 正例:
const obj = {
lukeSkywalker,
};
反例:
const obj = {
lukeSkywalker:lukeSkywalker,
};
g. 【推薦】在對象屬性聲明前把簡寫的屬性分組。說明:因爲這樣能清楚地看出哪些屬性使用了簡寫。constanakinSkywalker = 'Anakin Skywalker'; const lukeSkywalker = 'Luke Skywalker';
正例:
const obj = { lukeSkywalker, anakinSkywalker,episodeOne: 1,
twoJedisWalkIntoACantina:2,
};
反例:
const obj = { episodeOne: 1,
twoJedisWalkIntoACantina: 2, lukeSkywalker, anakinSkywalker,
};
4. 數組
a. 【推薦】使用字面值創建數組。
b. 【推薦】向數組添加元素時使用 Arrary#push 替代直接賦值。
c. 【推薦】使用拓展運算符 ... 複製數組。正例:
const itemsCopy = [...items]; 反例:
const len = items.length; const itemsCopy = [];
for (let i = 0; i < len; i++) { itemsCopy[i] =items[i];
}
d. 【推薦】使用 Array#from 把一個類數組對象轉換成數組。說明:
const foo = document.querySelectorAll('.foo'); const nodes =Array.from(foo);
5. 解構
a. 【推薦】使用解構存取和使用多屬性對象。說明:因爲解構能減少臨時引用屬性。
正例:
function getFullName({ firstName, lastName }) { return`${firstName} ${lastName}`;
}
反例:
functiongetFullName(user) {
const firstName =user.firstName; const lastName = user.lastName; return `${firstName}${lastName}`;
}
b. 【推薦】對數組使用解構賦值。const arr = [1, 2, 3, 4];
正例:
const [first, second] = arr; 反例:
const first = arr[0]; const second = arr[1];
c.【推薦】需要回傳多個值時,使用對象解構,而不是數組解構。
6. 字符串
a. 【推薦】字符串使用單引號 ' '。
b. 【推薦】字符串超過 80 個字節應該使用字符串連接號換行。
c. 【參考】過度使用字串連接符號可能會對性能造成影響。
d. 【推薦】程序化生成字符串時,使用模板字符串代替字符串連接。
7. 函數
a. 【推薦】使用函數聲明代替函數表達式
說明:因爲函數聲明是可命名的,所以他們在調用棧中更容易被識別。此外,函數聲明會把整個函數提升(hoisted),而函數表達式只會把函數的引用變量名提升。這條規則使得箭頭函數可以取代函數表達式。
正例:function foo() { }
反例:const foo = function () { };
b. 【強制】永遠不要在一個非函數代碼塊(if、while 等)中聲明一個函數,把那個函數賦給一個變量。瀏覽器允許你這麼做,但它們的解析表現不一致。
c. 【參考】ECMA-262 把 block定義爲一組語句。函數聲明不是語句。
正例: let test;
if (currentUser) { test = () => {
console.log('Yup.');
};
}
反例:
if (currentUser) { function test() {
console.log('Nope.');
}
}
d. 【強制】永遠不要把參數命名爲 arguments。這將取代原來函數作用域內的 arguments 對象,可以選擇 rest 語法 ... 替代。
正例:
function concatenateAll(...args) { return args.join('');
}
反例:
functionconcatenateAll() {
const args =Array.prototype.slice.call(arguments);
returnargs.join('');
}
e. 【推薦】直接給函數參數賦值時需要避免副作用。
f. 【推薦】比較簡單的情況下使用三元條件判斷。
8. 箭頭函數
a. 【推薦】當你必須使用函數表達式(或傳遞一個匿名函數)時,使用箭頭函數符號。
說明:因爲箭頭函數創造了新的一個 this 執行環境,通常情況下都能滿足你的需求,而且這樣的寫法更爲簡潔。如果你有一個相當複雜的函數,你或許可以把邏輯部分轉移到一個函數聲明上。
正例:
[1, 2, 3].map((x) => {
return x * x;
});
反例:
[1, 2, 3].map(function (x) { return x * x;
});
b. 【推薦】如果一個函數適合用一行寫出並且只有一個參數,那就把花括號、圓括號和 return 都省略掉。如果不是,那就不要省略。
說明:語法糖。在鏈式調用中可讀性很高。正例:
[1, 2, 3].map(x=> x * x);
[1, 2, 3].reduce((total, n) => { return total + n;
}, 0);
9. 構造函數
a. 【推薦】總是使用 class 類。避免直接操作 prototype。說明:因爲 class 語法更爲簡潔更易讀。
正例:
class Queue {
constructor(contents = []) { this._queue =[...contents];
}
pop() {
const value = this._queue[0]; this._queue.splice(0, 1); returnvalue;
}
}
反例:
function Queue(contents = []) { this._queue =[...contents];
Queue.prototype.pop = function() { const value =this._queue[0]; this._queue.splice(0, 1); return value;
}
b. 【推薦】使用 extends 繼承。
說明:因爲 extends 是一個內建的原型繼承方法並且不會破壞instanceof。正例:
class PeekableQueue extends Queue { peek() {
return this._queue[0];
}
}
反例:
const inherits = require('inherits'); functionPeekableQueue(contents) {
Queue.apply(this, contents);
}
inherits(PeekableQueue, Queue); PeekableQueue.prototype.peek =function() {
returnthis._queue[0];
c. 【參考】方法可以返回 this 來幫助鏈式調用。
d. 【參考】可以寫一個自定義的 toString() 方法,但要確保它能正常運行並且不會引起副作用。
10. 模塊
a. 【參考】總是使用模組 (import/export) 而不是其他非標準模塊系統。你可以編譯爲你喜歡的模塊系統。
b. 【推薦】不要使用通配符 import。
c. 【推薦】不要從 import 中直接 export。
說明:雖然一行代碼簡潔明瞭,但讓import 和 export 各司其職讓事情能保持一致。
正例:
import { es6 } from './AirbnbStyleGuide'; export default es6;
反例:export { es6 as default } from './airbnbStyleGuide';
11. 迭代器和選擇器
a. 【推薦】不要使用 iterators。使用高階函數例如 map() 和 reduce() 替代 for-of。
說明:這加強了我們不變的規則。處理純函數的回調值更易讀,這比它帶來的副作用更重要。
const numbers = [1, 2, 3, 4, 5]; 正例:
let sum = 0;
numbers.forEach((num) => sum += num); sum === 15;
正例:
const sum = numbers.reduce((total, num) => total + num, 0); sum=== 15;
反例:
let sum = 0;
for (let num of numbers) { sum += num;
}
sum === 15;
b. 【推薦】現在還不要使用 generators。
12. 屬性
a. 【強制】使用‘ . ’來訪問對象的屬性。
b. 【推薦】當通過變量訪問屬性時使用中括號[]。說明:
const luke = {
jedi: true, age: 28,
};
function getProp(prop) { return luke[prop];
}
const isJedi =getProp('jedi');
13. 變量
a. 【推薦】使用 var 聲明每一個變量。
b. 【參考】將所有的 const 和 let 分組。
c. 【參考】在你需要的地方給變量賦值,但請把它們放在一個合理的位置。
14. 提升
a. 【參考】var 聲明會被提升至該作用域的頂部,但它們賦值不會提升。說明:
// 我們知道這樣運行不了
// (假設 notDefined 不是全局變量) function example() {
console.log(notDefined);// => throws a ReferenceError
}
// 由於變量提升的原因,
// 在引用變量後再聲明變量是可以運行的。
// 注:變量的賦值 `true` 不會被提升。function example() {
console.log(declaredButNotAssigned); // => undefined vardeclaredButNotAssigned = true;
}
// 編譯器會把函數聲明提升到作用域的頂層,
// 這意味着我們的例子可以改寫成這樣: function example() {
let declaredButNotAssigned; console.log(declaredButNotAssigned); //=> undefined declaredButNotAssigned = true;
}
b. 【參考】匿名函數表達式的變量名會被提升,但函數內容並不會。說明:
function example() { console.log(anonymous); // =>undefined
anonymous(); // => TypeError anonymous is not a function varanonymous = function() {
console.log('anonymousfunction expression');
};
}
c. 【參考】命名的函數表達式的變量名會被提升,但函數名和函數函數內容並不會。
說明:
function example() { console.log(named); // =>undefined
named(); // => TypeError named is not a function superPower(); //=> ReferenceError superPower is not defined
var named = function superPower() {console.log('Flying');
};
}
// the same istrue when the function name
// is the same as the variable name. function example() {
console.log(named);// => undefined
named(); // => TypeError named is not a function var named =function named() {
console.log('named');
}
}
d. 【參考】函數聲明的名稱和函數體都會被提升。說明:
function example() { superPower(); // => Flyingfunction superPower() {
console.log('Flying');
}
}
15. 比較運算符和等號
說明:
console.log(false == null ) // false console.log( false == undefined ) // falseconsole.log( false == 0 ) // true
console.log( false == '' ) //true console.log( false == NaN ) // false console.log( null == undefined ) //true console.log( null == 0 ) // false
console.log( null == '' ) //false console.log( null == NaN ) // false console.log( undefined == 0) // false console.log( undefined == '') // false console.log( undefined == NaN) //false console.log( 0 == '' ) //true console.log( 0 == NaN ) // false
a. 【推薦】優先使用 === 和 !== 而不是 == 和 !=。
b. 【參考】條件表達式例如 if 語句通過抽象方法 ToBoolean 強制計算它們的表達式並且總是遵守下面的規則:
對象 被計算爲 true 、Undefined 被計算爲 false、
Null 被計算爲 false、布爾值 被計算爲 布爾的值 、
數字 如果是 +0、-0、或 NaN 被計算爲 false, 否則爲 true 、字符串 如果是空字符串 '' 被計算爲 false,否則爲true。
c. 【推薦】使用簡寫。正例:
if (name) {}
if (collection.length) {} 反例:
if (name !== ''){}
if(collection.length > 0) {}
16. 代碼塊
a. 【推薦】使用大括號包裹所有的多行代碼塊。
b. 【參考】如果通過 if和 else 使用多行代碼塊,把 else 放在 if 代碼塊關閉括號的同一行。
正例:
if (test) {
thing1( );
} else {
thing2( );
}
反例:
if (test) {
thing1( );
}
else {
thing2( );
}
17. 註釋
a. 【推薦】使用/** ... */ 作爲多行註釋,包含描述、指定所有參數和返回值的類型和值。
b. 【推薦】使用 //作爲單行註釋。在評論對象上面另起一行使用單行註釋。在註釋前插入空行。
c. 【推薦】使用 // FIXME: 標註問題。
d. 【推薦】使用 // TODO: 標註問題的解決方式。
18. 空白
a. 【推薦】使用 2 個空格作爲縮進。
b. 【推薦】在花括號前放一個空格。
c. 【推薦】在控制語句(if、while 等)的小括號前放一個空格。在函數調用及聲明中,不在函數的參數列表前加空格。
正例:
function fight() { console.log('Swooosh!');
}
反例:
function fight () { console.log ('Swooosh!');
}
d. 【推薦】使用空格把運算符隔開。正例:const x = y + 5;
反例:const x=y+5;
e. 【推薦】在文件末尾插入一個空行。
f. 【推薦】在使用長方法鏈時進行縮進。使用前面的點 . 強調這是方法調用而不是新語句。
正例:
$('#items')
.find('.selected') 反例:
$('#items'). find('.selected')
g. 【推薦】在塊末和新語句前插入空行。
19. 逗號
a. 【推薦】行首逗號:不需要。正例:
const story = [once,
upon
];
反例:
const story =[
once
, upon
];
b. 【推薦】行首逗號:不需要。正例:
const heroes = [
'Batman', 'Superman',
];
反例:
const heroes =[
'Batman', 'Superman'
];
20. 分號
正 例 : (() => {
const name = 'Skywalker'; return name;
})();
反 例 : (function(){
const name = 'Skywalker' return name
})()
21. 類型轉換
a. 【推薦】在語句開始時執行類型轉換。
b. 【推薦】轉字符串。
正例:consttotalScore = String(this.reviewScore); 反例:consttotalScore = this.reviewScore + '';
c. 【推薦】對數字使用 parseInt 轉換,並帶上類型轉換的基數。const inputValue= '4';
正例:
const val = parseInt(inputValue, 10); 、 const val = Number(inputValue);
反例:const val = parseInt(inputValue); 、const val = inputValue >>0;
d. 【參考】如果因爲某些原因 parseInt 成爲你所做的事的瓶頸而需要使用位操作解決性能問題時,留個註釋說清楚原因和你的目的。
正例:
/**
* 使用 parseInt 導致我的程序變慢,
* 改成使用位操作轉換數字快多了。
*/
const val =inputValue >> 0;
e. 【推薦】布爾。const age = 0;
正例:const hasAge =!!age; 、 const hasAge = Boolean(age); 反例:consthasAge = new Boolean(age);
22. 命名規則說明:
帕斯卡命名法:在命名的時候將首字母大寫。
駱駝式命名法:當變量名或函數名是由一個或多個單詞連結在一起,而構成的唯一識別字時,第一個單詞以小寫字母開始;從第二個單詞開始以後的每個單詞的首字母大寫都採用大寫字母。
a. 【推薦】避免單字母命名。命名應具備描述性。
b. 【推薦】使用駝峯式命名對象、函數和實例。
c. 【推薦】使用帕斯卡式命名構造函數或類。
d. 【推薦】使用下劃線 _開頭命名私有屬性。正例:this._firstName = 'Panda';
反例 :this.firstName = 'Panda';
e. 【推薦】別保存 this 的引用。使用箭頭函數或 Function#bind。
f. 【推薦】如果你的文件只輸出一個類,那你的文件名必須和類名完全保持一致。
class CheckBox{}
export defaultCheckBox;
正例:import CheckBox from'./CheckBox';
反 例 :import CheckBoxfrom './checkBox'; 、 import CheckBox from './check_box';
g. 【推薦】當你導出默認的函數時使用駝峯式命名。你的文件名必須和函數名完全保持一致。
function makeStyleGuide() {} export default makeStyleGuide;
h. 【推薦】當你導出單例、函數庫、空對象時使用帕斯卡式命名。
23. 存取器
a. 【推薦】屬性的存取函數不是必須的。
b. 【推薦】如果你需要存取函數時使用 getVal() 和 setVal('hello')。正例:dragon.setAge(25); 、 dragon.getAge();
反例:dragon.age(25); 、dragon.age();
c. 【推薦】如果屬性是布爾值,使用 isVal() 或 hasVal()。正例:
if (!dragon.hasAge()) { return false;
}
反例:
if (!dragon.age()) { return false;
}
d. 【推薦】創建 get() 和 set() 函數是可以的,但要保持一致。
24. 事件
a. 【推薦】當給時間附加數據時(無論是 DOM 事件還是私有事件),傳入一個哈希而不是原始值。這樣可以讓後面的貢獻者增加更多數據到事件數據而無需找出並更新事件的每一個處理器。
正例:
$(this).trigger('listingUpdated',{ listingId : listing.id });
$(this).on('listingUpdated', function(e, data) { }); 反例:
$(this).trigger('listingUpdated',listing.id);
$(this).on('listingUpdated',function(e, listingId) { });
25. jQuery
a. 【推薦】使用 $作爲存儲 jQuery 對象的變量名前綴。正例:const$sidebar = $('.sidebar');
反例:const sidebar = $('.sidebar');
b. 【推薦】緩存 jQuery 查詢。正例:
functionsetSidebar() {
const $sidebar =$('.sidebar');
$sidebar.hide();
$sidebar.css({
'background-color':'pink'
});
}
反例:
functionsetSidebar() {
$('.sidebar').hide();
$('.sidebar').css({ 'background-color': 'pink'
});
}
c. 【推薦】對有作用域的 jQuery 對象查詢使用 find。
正 例 :$sidebar.find('ul').hide(); 、$('.sidebar > ul').hide(); 、
$('.sidebarul').hide();
反 例 :$('ul', '.sidebar').hide(); 、$('.sidebar').find('ul').hide();
(二) HTML 編碼規範
1. 文檔規範
a. 【推薦】使用 HTML5 的文檔聲明類型 : <!DOCTYPE html>。說明:
如果你的頁面添加了<!DOCTYP>那麼,那麼就等同於開啓了標準模式。瀏覽器會按照 W3C 標準解析渲染頁面。
2. 腳本加載
只兼容現代瀏覽器推薦:
<html>
<head>
<linkrel="stylesheet" href="main.css">
<scriptsrc="main.js" async></script>
</head>
<body>
<!-- bodygoes here -->
</body>
</html>
所有瀏覽器中推薦:
<html>
<head>
<linkrel="stylesheet" href="main.css">
</head>
<body>
<!-- bodygoes here -->
<scriptsrc="main.js" async></script>
</body>
</html>
a. 【推薦】所有瀏覽器中,js 放在下面,css 放在上面。
b. 【推薦】只兼容現代瀏覽器,可以使用HTML5 的新屬性 async,將腳本文件放在<head>內。
3. 語義化
說 明 :<header> 、 <nav>、 <footer> 等
a. 【推薦】根據元素其被創造出來時的初始意義來使用它。
b. 【推薦】意思就是用正確的標籤幹正確的事,而不是隻有 div 和 span。
4. alt 標籤不爲空
說明:網速太慢、src 屬性中的錯誤、瀏覽器禁用圖像、用戶使用的是屏幕閱讀器等。
5. 結構、表現、行爲三者分離說明:
不使用超過一到兩張樣式表。
不使用超過一到兩個腳本(學會用合併腳本)。
不使用行內樣式(<style>.no-good{}</style>)。
不在元素上使用 style 屬性(<hr style="border-top: 5px solidblack">)。
不使用行內腳本(<script>alert('nogood')</script>)。
不使用表象元素(i.e. <b>, <u>, <center>, <font>,<b>)。不使用表象 class 名(i.e. red, left, center)。
a. 【推薦】儘量在文檔和模板中只包含結構性的HTML;而將所有表現代碼, 移入樣式表中;將所有動作行爲,移入腳本之中。
b. 【推薦】在此之外,爲使得它們之間的聯繫儘可能的小,在文檔和模板中
也儘量少地引入樣式和腳本文件
6. HTML 只關注內容
a. 【參考】HTML 只顯示展示內容信息。
b. 【參考】不要引入一些特定的 HTML 結構來解決一些視覺設計問題。
c. 【參考】不要將 img 元素當做專門用來做視覺設計的元素。
d. 【參考】樣式上的問題應該使用 css 解決。
7. 屬性順序
說明:id>class>name>src
(三) CSS 編碼規範
1. 【強制】ID 選擇器
說明:ID 選擇器給規則聲明帶來了不必要的高優先級,而且 ID 選擇器不可重用
正例:
.good{border:0;} 反例:
#bad{border:0;}
2. 【強制】JavaScript 鉤子
說明:避免在 css 和 JavaScript 中綁定相同的類。否則開發者在重構時通常會出現一下情況:輕則浪費時間在對照查找每個要改變的類,重則因爲
害怕破壞功能而不敢作爲更改。
3. 【強制】使用子選擇器
說明:css 選擇器的查找算法是從右到左,如果使用後代選擇器,消耗性能大;還會有頭疼的設計問題
正例:
.good > p {border:0;} 反例:
.good p{border:0;}
4. 【推薦】儘量使用縮寫屬性
說明:代碼易維護性和代碼量少不可兼得,所以這裏不強制舉例:1.border:10px 10px 10px 0;
2.border:10px; border-left-width:0;
5. 【強制】0 後面不帶單位
說明:爲避免單位轉換而損失效率,爲 0 時不加單位。在定義無邊框樣式時,使用 0代替 none。在 IE6、IE7 下,border:0,其實設置的是border-
width:0;border:none,其實設置的是 border-style:none。在現代瀏覽器,
border:0 和 border:none,設置所有屬性重置(ps:各個瀏覽器版本表現形式不同)
即:在不兼容低版本IE 的情況下,這兩個沒有差別
正例:
margin:0;反例:
margin:0px;padding:0em;border:0rem;
6. 屬性格式
a. 【強制】屬性和值(但屬性和冒號之間沒有空格)的之間始終使用一個空格
正例:
.good{
margin: 10px;
}
反例:
.bad{
margin:10px;
}
b. 【強制】每個選擇器和屬性聲明總是使用新的一行正例:
.good{
border:0; margin:0;
}
反例:
.bad{
border:0; margin:0;
}
c. 【推薦】屬性選擇器或屬性值用雙引號(“”)而不是單引號(‘’)括起來
//官方推薦,屬性選擇器和屬性值都不帶引號
d. 【推薦】URL 值不要使用引號
說明:不加引號會有一些 edge cases,增加了認知負擔,加了引號之後就是常見的字符串規則了
正例:
.good{
background-img:url(www.baidu.com);
}
反例:
.bad{
Background-img:url(“www.baidu.com”);
}
7. 【推薦】屬性聲明順序說明:
1. 不強制要求聲明的書寫順序:佈局類屬性 盒模型 字體 字體 其他
2. 無前綴屬性一定要寫在最後
正例:
.dialog{
/* 定 位 */ margin:auto; position:ansolute;top:0;
bottom:0; right:0;left:0;
/* 盒 模 型 */ width:500px; height:300px; padding:10px 20px;
/* 皮 膚 */ background:#fff; color:#333; border:1px solid;
-webkit-border-radius:5px;
-moz-border-radius:5px; border-radius:5px;
}
反例:
.dialog{
margin:auto; position:ansolute; top:0; width:500px; height:300px;
padding:10px 20px; bottom:0;
right:0; background:#fff; color:#333; border:1px solid; left:0;
-webkit-border-radius:5px; border-radius:5px;
-moz-border-radius:5px;
}
8. 註釋
a. 【強制】與 JS 保持一致
9. Sass 屬性聲明的排序
a. 嵌套選擇器
2. 【強制】請不要讓嵌套選擇器的深度超過 5 層說明:影響渲染效率
3. 【強制】不要嵌套 ID 選擇器
說明:ID 選擇器不可重用,並且增加了權重和跟 class 選擇器渲染速度差距不大。
b.順序@extend @include 自身嵌套
二、 React/JSX 編碼規範
1. 基本規範
a.【強制】原則上每個文件只寫一個組件,多個無狀態組件可以放在單個文件中
b. 【強制】使用 JSX 語法編寫 React 組件,而不是 React.createElement
2. 創建組件的三種方式
a. 如果你的組件有內部狀態或者 refs, 推薦使用 class extends
React.Component 而不是 React.createClass 正例:
class Listing extends React.Component { state = {
hello:‘hello’
}
render() {
return<div>{this.state.hello}</div>;
}
}
反例:
const Listing = React.createClass({ render() {
return<div>{this.state.hello}</div>;
}
});
b.如果你的組件沒有狀態或者 refs,推薦使用普通函數(非箭頭函數)而不是類正例:
function Listing({ hello }) { return<div>{hello}</div>;
}
反例:
class Listing extends React.Component { render() {
return<div>{this.props.hello}</div>;
}
}
3. Mixins
a.不要使用 mixins
說明:因爲 Mixins 會增加隱式依賴,導致命名衝突,並且會增加複雜度。
4. 命名
a.擴展名
1. 【強制】文件名:使用帕斯卡命名。正例:
ReservationCard.jsx
反例:
reservationCard.jsx
2. 【強制】React 組件名:使用帕斯卡命名,實例使用駝峯式命名
說明:標籤名的大寫與否是React 組件還是 HTML 元素的辨別標誌
b.組件命名
1. 【強制】組件名與當前文件名一致。正例:
import Footer from ‘./Footer’; 反例:
import Footerfrom ‘./Footer/Footer’
c.高階組件命名
1. 【強制】生成一個新的組件時,其中的組件名 displayName 應該爲高階組件名和傳入組件名的組合。
說明:高階組件 withFoo(),當傳入一個 Bar 組件的時候,生成的組件 名 displayName 應 該爲 withFoo(Bar) 。 應 爲 一 個 組 件 的
displayName 可能在調試工具或錯誤信息中使用到。清晰合理的命名, 能幫助我們更好的理解組件執行過程,更好的 Debug
d. 屬性命名
1. 【強制】避免使用 DOM 相關的屬性來用命名自定義屬性。
說明:對於 style 和 className 這樣的屬性名,React它們代表一些特殊的含義
正例:
<MyComponent variant=”fancy” /> 反例:
<MyComponentstyle=”fancy” />
5. 聲明組件:
a. 【強制】不要使用 displayName 來命名 React 組件,而是使用引用來命名組件。
正例:
export default class MyComponent extends React.Component{} 反例:
export default React.createClass({displayName:”MyComponent”
})
6. 代碼縮進:
a. 【強制】遵循備註文案的 JSX 語法縮進/格式正例:
<Foo
longParam=”bar”
createName=”張三”
/> 反例:
<FoolongParam=”bar”
cteateName=”張三”/>
7. 【強制】使用雙引號:
說明:因爲 HTML 屬性也是用雙引號,因此 JSX 的屬性也遵循此約定正例:
<Foo bar=”bar” />反例:
<Foobar=’bar’ />
8. 空格:
a. 【強制】總是在自動關閉的標籤前加一個空格,正常情況下不需要換行正例:
<Foo bar=”bar” /> 反例:
<Foobar=”bar”/>
b. 【強制】不要在 JSX{}引用括號裏兩邊加空格正例:
<Foo bar={bar} /> 反例:
<Foo bar={ bar}/>
9. 屬性:
a. 【強制】JSX 屬性名使用駝峯式風格正例:
<Foo
username=”張三”
phoneNumber={123456}
/> 反例:
<Foo
UserName=” 張 三 ” phone_number={123456}
/>
b. 【強制】如果屬性值爲 true,可以直接省略說明:props(屬性)默認爲”true”
正例:
<MyTextBox autocomplete /> 反例:
<MyTextBox autocomplete={true}/>
c. 【強制】<img>標籤總是添加 alt 屬性。如果圖片以陳述方式顯示,alt 可爲空,或者<img>要包含 role=”presentation”。
正例:
反例:
<img src=”www.baidu.com”alt=”” />
<img src=”www.baidu.com”role=”presentation” />
<img src=”www.baidu.com”alt=”頭像”
<img src=”www.baidu.com”/>
d. 【強制】不要在 alt 值裏使用如”image”,”photo”,or ”picture”包括圖片含義這樣的詞,中文同理。
說明:因爲屏幕助讀器已經把 img 標籤標註爲圖片了,所以沒有必要再在 alt 裏重複說明。
正例:
<img src=”www.baidu.com” alt=”Me waving hello” />反例:
<img src=”www.baidu.com” alt=”Picture of me wainghello” />
e. 【強制】使用正確的 aria role 屬性值 ARIA roles 正例:
<div role=”button” /> 反例:
<divrole=”datepicker” />
f. 【強制】不要在標籤上使用 accesskey 屬性。
說明:因爲屏幕助讀器在快捷鍵與鍵盤命名是造成的不統一性會導致閱讀性更加複雜。
正例:
<div /> 反例:
<div accessKey=”h”/>
g. 【推薦】避免使用數組的 index 來作爲屬性 key 的值,推薦使用唯一 ID。正例:
{todos.map( item => (
<Todo
{…todo} Key={item.id}
/>
))}
反例:
{todos.map((item,index) =>
<Todo
{…todo} Key={index}
)}
h. 【推薦】對於所有非必填屬性,總是手動去定義 defaultProps 屬性。
說明:因爲 propTypes 可以作爲組件的文檔說明,而defaultProps 使閱讀代碼的人不需要去假設默認值。另外,顯示的聲明默認屬性可以讓你的組件跳過屬性的類型的檢查。
正例:
function SFC({foo, bar, children }) {
return<div>{foo}{bar}{children}</div>;
}
SFC.propTypes= {
foo: PropTypes.number.isRequired, bar: PropTypes.string,
children: PropTypes.node,
};
SFC.defaultProps = { bar: '',
children: null,
};
反例:
function SFC({foo, bar, children }) {
return<div>{foo}{bar}{children}</div>;
}
SFC.propTypes ={
foo: PropTypes.number.isRequired, bar: PropTypes.string,
children:PropTypes.node,
};
10. Refs
a.【強制】總是使用回調函數方式定義ref
正例:
<Foo
Ref={(ref) =>{this.myRef=ref;}}
/> 反例:
<Foo
Ref=”myRef”
/>
11. 括號:
a.【強制】將多行 JSX 標籤寫在()裏正例:
render(){
return(
<MyComponent className=”long body” foo=”bar”>
<MyChild />
</MyComponent>
)
}
正例:
Render(){
Return<MyComponent
className=”long body” foo=”bar”>
<MyChild />
</MyComponent>
}
12. 標籤:
a. 【強制】對於沒有子元素的標籤,總是自關閉標籤正例:
<Foo className=”bar” /> 反例:
<Foo
className=”bar”>
</Foo>
b. 【強制】如果組件有多行的屬性,關閉標籤時新建一行正例:
<Foo
bar=”bar” baz=”baz”
/> 反例:
<Foo
bar=”bar” baz=”baz” />
13. 函數/方法:
a. 【強制】使用箭頭函數來獲取本地變量。
說明:因爲箭頭函數的上下文(this)是其上一個 scope 的 this 正例:
function ItemList(props){ return(
<ul>
{props.items.map((item,index)=> (
<Item
Key={item.key}
onClick={() =>
doSomethingWith(item.name,index)}
/>
) }
</ul>
)
}
反例:
function ItemList(props){ return(
<ul>
{props.items.map(function(item,index){
<Item
Key={item.key}
onClick={()=>doSomethingWith(item.name,index)}
})}
</ul>
)
}
b.【強制】當在 render()裏使用事件處理方法時,提前在構造函數裏把 this 綁定上去。
說明:因爲在每次 render 過程中,在調用 bind 都會新建一個新的函數, 浪費資源。
正例:
Class Foo extends React.Component { constructor(props) {
super(props);
this.onClickDiv = this.onClickDiv.bind(this);
}
onClickDiv() {
// do stuff
}
render(){
return <div onClick={this.onClickDiv} />;
}
}
反例:
Class Foo extends React.Component { onClickDiv() {
// do stuff
}
render() {
return <div onClick={this.onClickDiv.bind(this)} />;
}
}
c.【強制】在 React 組件中,不要給所謂的私有函數添加_前綴。說明:JS 本質是就不支持私有變量。
正例:
onClickSubmit(){} 反例:
_onClickSubmit()
d.【強制】在 render 方法中總是確保 return 返回值說明:React 規定 render 函數必須有 return
正例:
render(){
return ( <div/>)
}
反例:
render(){
(<div/>)
}
14. 組件生命週期書寫順序
a. 【強制】class Index extends React.Component 的生命週期函數說明:可以知道各個生命週期做了一些什麼
b. 【推薦】定義 propTypes,defaultProps,contextTypes 等屬性說明:減少對undefined 和 null 的判斷
15. isMounted
a.【強制】不要使用 isMounted。說明:es6 不支持,並且棄用很久了
三、 Ant Design Pro 使用規範
(一)effects 命名規範([]爲選填)
1. 使用 submit 開頭提交表單信息。
a. 【推薦】分步驟表單最終提交,使用submitStepsForm。反例:submitForm
b. 【推薦】普通表單,使用submitForm。
c. 【推薦】一個頁面存在多個表單提交的情況,使用 submit[表單名]Form。
2. 使用 fetch 開頭獲取數據。
a. 【推薦】獲取列表請求:fetchList[For*(功能名)][By*(條件)]。
b. 【推薦】獲取詳情:fetchDetail[For*(功能名)][By*(條件)]。
3. 加載(Loading)命名。
a. 【推薦】changeLoading[For*(功能名)]。
4. 使用 save 開頭保存數據。
a. 【推薦】保存列表 saveListFor(數據名稱)。
b. 【推薦】保存其他類型數據saveDataFor(數據名稱)。
(二) Model 規範
1. 【強制】使用過程中儘量避免複雜的值操作,值操作可通過在 service 添加 async 方法來轉化或者使用 factory 類進行轉換。
反例:在 Model 的 reducers 裏面直接複雜轉換
(三)style與 className 的選擇
1. 【強制】小於 3 個 css 屬性可以直接使用 style。
2. 【強制】大於等於 3 個屬性必須先到 less 文件中。
(四)state 命名規範
1. 【推薦】新增與編輯,showEdit[*(功能名)]。
2. 【推薦】詳情,showDetail[*(功能名)]。
3. 【推薦】其它功能名統一爲(funcName)[*(功能名)]。
4. 【強制】臨時數據與控制顯示隱藏的 state 中間需留空行。
(五)Ant Design 控件規範
1. Select 篩選建議:
a. 說明:複雜值選項可使用 labelInValue 屬性,但是注意傳輸值以及接受編輯值的轉換(避免數據轉化出錯)。
b. 【推薦】本地搜索儘量使用 fliterOptions。
c. 【推薦】Option 實際長度大於 select 的 ant 會用省略號代替,若要顯示完整內容,可設置 dropdownMatchSelectWidth 爲 false。
2. 數據驗證標準化:
a. 【強制】身份證、電話/手機、銀行卡、數字、字數、非空、XSS 防禦(特殊符號)、防止 XSS 回顯、特殊比較(使用 validate 進行比較)、郵箱。
3. FileUpload 規範化
a. 【強制】統一使用 fileList 進行文件控制。
b. 【強制】對 beforeUpload 中的驗證進行統一處理。
4. 對於刪除這類的操作必須給予提示(Popconfirm )
a. 【強制】點刪除提示‘是否刪除’。
b. 【推薦】點取消不會保存的數據提示‘取消不會保存是否取消’
四、 開發流程規範
以數據爲始,以頁面爲終
說明:showDoc 先行審覈,預測會出現的問題反饋服務端,存在爭議立刻反饋產品再進行
mock、service、model 的搭建,最終撰寫view 層。
反例:先寫 view 層,開發中途遇到問題再找服務端產品問題,使得開發不連貫割裂開來,缺乏整體思維。
五、 測試規範
1、業務先行,不妨礙業務的疑難雜症可延期處理。
2、使用測試用例跑代碼,避免提測後依然出現該問題。
3、自測+測試用例通不過不可確認任務完成。
4、仔細。
附 1: 版本歷史
版本號 | 更新日期 | 備註 |
1.0.0 | 2018.7.10 | 第一版 |
1.0.1 | 2018.7.11 | 更新目錄信息 |
附 2: 參考文獻
1、 阿里巴巴 Java 開發手冊
2、 Airbnb 前端規範