前端开发规范

通用规范

命名

目录及文件命名

  • 普通目录及文件采用全小写
  • 模块文件夹或者组件文件(如在components下的文件)采用大驼峰(例:LeftBar.js
  • 其他采用小驼峰

变量命名

  • 小驼峰命名
  • 类型+对象描述或属性的方式
// 不推荐
var getTitle = "LoginTable"

// 推荐
let tableTitle = "LoginTable"

函数命名

  • 小驼峰方式 ( 构造函数使用大驼峰命名法 )
  • 前缀为动词
动词 含义 返回值
can 判断是否可执行某个动作 (权 ) 函数返回一个布尔值。true:可执行;false:不可执行
has 判断是否含有某个值 函数返回一个布尔值。true:含有此值;false:不含有此值
is 判断是否为某个值 函数返回一个布尔值。true:为某个值;false:不为某个值
get 获取某个值 函数返回一个非布尔值
set 设置某个值 无返回值、返回是否设置成功或者返回链式对象
//是否可阅读
function canRead(){
    return true;
}

//获取姓名
function getName{
    return this.name
}

注释

单行注释

  1. 单独一行://(双斜线)与注释文字之间保留一个空格
  2. 在代码后面添加注释://(双斜线)与代码之间保留一个空格,并且//(双斜线)与注释文字之间保留一个空格。
  3. 注释代码://(双斜线)与代码之间保留一个空格。
// 调用了一个函数 <= 1)单独在一行
setTitle();
 
var maxCount = 10; // 设置最大量 <= 2)在代码后面注释
 
// setName(); // <= 3)注释代码

多行注释

  • 若开始(/*)和结束(*/)都在一行,推荐采用单行注释
  • 若至少三行注释时,第一行为/*,最后行为*/,其他行以开始,并且注释文字与保留一个空格。
  • 一般用于函数(方法)
/*
* 代码执行到这里后会调用setTitle()函数
* setTitle():设置title的值
*/
setTitle();

需要注释的地方

  1. 公共组件使用说明
  2. 各组件中重要函数或者类说明
  3. 复杂的业务逻辑处理说明
  4. 特殊情况的代码处理说明,对于代码中特殊用途的变量、存在临界值、函数中使用的hack、使用了某种算法或思路等需要进行注释描述
  5. 多重 if 判断语句

HTML规范

  • 缩进使用tab(2 个空格)
  • 嵌套的节点应该缩进
  • 在属性上,使用双引号,不要使用单引号
  • 属性名全小写,用中划线(-)做分隔符
  • 要在自动闭合标签结尾处使用斜线
  • 正确合理使用navheaderasidefooterarticlesection等语义标签,不要全篇
  • 在编写 HTML 代码时,需要尽量避免多余的父节点
  • 尽量避免行内样式(style的方式)
  • <img> 标签的alt属性指定文本
  • 尽量使用样式解决视觉设计元素,多考虑使用伪元素:before:after
  • css样式表在head标签内引用,js脚本引用在body结束标签之前引用

CSS规范

  • 缩进使用tab(2 个空格)
  • 命名必须由单词、中划线或数字组成
  • 不允许使用拼音(约定俗成的除外,如:youku, baidu),尤其是缩写的拼音、拼音与英文的混合
/* 不推荐 */
.xiangqing { sRules; }
.news_list { sRules; }
.zhuti { sRules; }

/* 推荐 */
.detail { sRules; }
.news-list { sRules; }
.topic { sRules; }
  • 每个声明结束都要加分号
  • url 的内容要用引号
  • 类名使用小写字母,以中划线分隔
  • 非必要的情况下 0 后面不用加单位
/* 不推荐 */
padding-bottom: 0px;
margin: 0em;

/* 推荐 */
padding-bottom: 0;
margin: 0;
  • 使用子选择器
/* 不推荐 */
.content .title {
  font-size: 2rem;
}

/* 推荐 */
.content > .title {
  font-size: 2rem;
}
  • 尽量使用缩写属性
/* 不推荐 */
padding-bottom: 2em;
padding-left: 1em;
padding-right: 1em;
padding-top: 0;

/* 推荐 */
padding: 0 1em 2em;

JS规范

缩进

使用 tab 缩进(2 个空格)

注释原则

  • As short as possible(如无必要,勿增注释):尽量提高代码本身的清晰性、可读性
  • As long as necessary(如有必要,尽量详尽):合理的注释、空行排版等,可以让代码更易阅读、更具美感
  • 注释单独一行的情况下,注释的//后面要跟一个空格
  • 注释如果和代码同一行,代码分号结束后,要跟一个空格,注释的//后也要跟一个空格

命名

  • 变量,使用驼峰命名,特殊命名按约定熟成命名(如:iOS,Android)
let loadingModules = {};
  • boolean 类型的变量使用 is 或 has 开头
let isReady = false;
let hasMoreCommands = false;

分号

统一要加分号

空格

以下几种情况不用写空格:

  • 对象的属性名后
  • 函数调用括号前
  • 数组的'['后和']'前
  • 运算符'('后和')'前

以下几种情况一定要写空格:

  • 三元运算符'?:'前后
  • 逗号后必须要有空格
  • 下列关键字前:else, while, catch, finally
  • 下列关键字后:if, else, for, while, do, switch, case, try, catch, finally, with, return, typeof
  • 单行注释'//'后(若单行注释和代码同行,则'//'前也需要),多行注释'*'后
  • 对象的属性值前
  • for 循环,分号后留有一个空格,前置条件如果有多个,逗号后留一个空格
  • 无论是函数声明还是函数表达式,'{'前一定要有空格
  • 函数的参数之间

这些后续会用 eslint 和 prettier 进行格式化

// 不推荐
var a = {
  b : 1
};

// 推荐
var a = {
  b: 1
};

// 不推荐
++x;
y++;
z = x ? 1:2;

// 推荐
++x;
y++;
z = x ? 1 : 2;

// 不推荐
var a = [ 1, 2 ];

// 推荐
var a = [1, 2];

// 推荐
var doSomething = function(a, b, c) {
  // do something
};

// 推荐
doSomething(item);

// 不推荐
for (let i = 0;i < 6;i++) {
  x++;
}

// 推荐
for (let i = 0; i < 6; i++) {
  x++;
}

空行

以下几种情况一定要有空行

  • 变量声明后(当变量声明在代码块的最后一行时,则无需空行)
  • 注释前(当注释在代码块的第一行时,则无需空行)

换行

换行的地方,行末必须有','或者运算符;
以下几种情况不需要换行:

  • 下列关键字后:else, catch, finally
  • 代码块'{'前

以下几种情况需要换行:

  • 代码块'{'后和'}'前
  • 变量赋值后
// 不推荐
var a = {
    b: 1
    , c: 2
};

x = y
    ? 1 : 2;

// 推荐
var a = {
    b: 1,
    c: 2
};

x = y ? 1 : 2;

// 推荐
if (condition) {
    ...
} else {
    ...
}

try {
    ...
} catch (e) {
    ...
} finally {
    ...
}

// 不推荐
function test()
{
    ...
}

// 推荐
function test() {
    ...
}

// 不推荐
var a, foo = 7, b,
    c, bar = 8;

// 推荐
var a,
    foo = 7,
    b, c, bar = 8;

引号

最外层统一使用单引号,除非字符串嵌套的情况

// 不推荐
var x = "test";

// 推荐
var y = 'foo',
  z = '<div id="test"></div>';

对象,数组

  • 对象属性名不需要加引号,如对象属性名是中划线命名的需要加引号(eslint 的 rules)
  • 对象以缩进的形式书写,不要写在一行(单个属性可以写一行,es6 导入方法时可以使用单行)
  • 数组、对象最后不要有逗号
// 推荐
var a = {
  b: 1,
  c: 2
};

括号

下列关键字后必须有大括号(即使代码块的内容只有一行):if, else, for, while, do, switch, try, catch, finally, with

// 不推荐
if (condition) doSomething();

// 推荐
if (condition) {
  doSomething();
}

undefined

  • 永远不要直接使用 undefined 进行变量判断
  • 使用 typeof 和字符串'undefined'对变量进行判断
// 不推荐
if (person === undefined) {
    ...
}

// 推荐
if (typeof person === 'undefined') {
    ...
}

三元操作符

  • 操作符始终写在前一行, 以免分号的隐式插入产生预想不到的问题
let x = a ? b : c;
let y = a ?
    longButSimpleOperandB : longButSimpleOperandC;
let z = a ?
        moreComplicatedB :
        moreComplicatedC;
  • 可以使用三元操作符替代 if 条件判断语句
// 不推荐
if (val != 0) {
  return foo();
} else {
  return bar();
}

// 推荐
return val ? foo() : bar();

异步

  • 用 Promises 替代回调
  • async/await 是较 Promises 更好的选择

其他

  • 优先使用ES6,ES7的写法,更简洁
  • 不要声明了变量却不使用
  • 数组中不要存在空元素
  • debugger 不要出现在提交的代码里
  • 尽量使用===代替==
  • 不使用eval()函数
  • 不再被调用的代码应及时删除
  • 尽量不手动操作 DOM

React

基础规则

  • 一个文件声明一个组件:尽管可以在一个文件中声明多个 React 组件,但是最好不要这样做;推荐一个文件声明一个 React 组件,并只导出一个组件;
  • 使用 JSX 表达式:不要使用 React.createElement 的写法;
  • 推荐使用函数式组件

React 中的命名

  • 组件名称: 推荐使用大驼峰命名;
  • 属性名称: React DOM 使用小驼峰命令来定义属性的名称,而不使用 HTML 属性名称的命名约定;
  • style 样式属性: 采用小驼峰命名属性的 JavaScript 对象;
// 组件名称
MyComponent
// 属性名称
onClick
// 样式属性
backgroundColor

JSX 写法

  • 当标签没有子元素的时候,始终使用自闭合的标签
// 推荐
<Component />

// 不推荐
<Component></Component>
  • 如果标签有多行属性,关闭标签要另起一行
// 推荐
<Component
  bar="bar"
  baz="baz" 
/>

// 不推荐
<Component
  bar="bar"
  baz="baz" />
  • 在自闭标签之前留一个空格
// 推荐
<Foo />

//不推荐 
<Foo/>

<Foo                 />

<Foo
 />
  • 当组件跨行时,要用括号包裹 JSX 标签
// 推荐
render() {
    return (
      <MyComponent className="long body" foo="bar">
        <MyChild />
      </MyComponent>
    );
  }
  
  // 不推荐
  render() {
    return <MyComponent className="long body" foo="bar">
             <MyChild />
           </MyComponent>;
  }

key 属性设置

避免使用index作为key使用

为组件绑定事件处理器

// 推荐
 handleClick = () => {
    console.log('this is:', this);
 }
 <button onClick={this.handleClick}> Click me </button>
  
  // 不推荐
   constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
 }
 handleClick(){
    console.log('this is:', this);
 }
 <button onClick={this.handleClick}> Click me </button>

State

  • 不要直接修改 state
  • State 的更新可能是异步的,推荐让 setState() 接收一个函数而不是一个对象

避免不必要 render 的写法

  • 使用shouldComponentUpdate,React.PureComponent,React.Memo避免不必要的 render
  • 但不能滥用,否则某些情况下会适得其反

路由加载

建议使用路由懒加载当前用户所需要的内容,这样能够显著地提高你的应用性能。尽管并没有减少应用整体的代码体积,但你可以避免加载用户永远不需要的代码,并在初始加载的时候减少所需加载的代码量。
使用React.lazy()或者第三方插件Loadable

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,193评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,306评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,130评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,110评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,118评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,085评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,007评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,844评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,283评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,508评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,395评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,985评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,630评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,797评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,653评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,553评论 2 352