未经允许不得转载
伙伴行前端开发手册
伙伴行研发中心前端组 编
目录
一、 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 前端规范