通用规范请参阅如下链接,如有冲突,以本文为准。
- https://github.com/airbnb/javascript
- http://alloyteam.github.io/CodeGuide/
- https://github.com/airbnb/javascript/tree/master/react
工具
项目中可以使用ESLint,辅助实现规范
IntelliJ IDEA the Java IDE(IntelliJ系列) 配置:
.eslintrc.js配置文件项目中已经加入,相关包已经安装了,注意第一次使用时npm install
eslint相关包
IDE 左上角 File -> Settings 打开settings,配置如下图
规范目的
为了提高团队开发效率,减少沟通障碍,以及便于后期维护扩展,特制定此规范。本规范一经大家确认,前端开发人员必须按照此规范进行前端开发。规范中如有不恰之处,请及时提出,经讨论后修改或完善此规范。
基本准则
模块化,组件化,语义化jsx(html),结构(jsx)表现(css或less)行为(js)分离。
文件规范
- 文件夹,文件命名,要使用语义化的英文,不允许使用缩写,数字。
- 架构相关,非业务文件归档至
assets/src/framework
; - 公共方法归档至
assets/src/common
,注意,这个文件夹存放公共的方法,而非组件,添加之后QQ或邮件通知全体前端开发人员; - 公共自定义组件归档至
assets/src/component
,并写好README,QQ或邮件通知全体前端开发人员; - 业务模块统一归档至
assets/src/page
; - 图片个数超过5个以上,要归档至当前模块文件夹下的
imgs/
文件夹中; - 一个功能模块新建一个文件夹,一个模块相关的文件(html,css,js,jsx,images),归档至对应的模块文件夹中,当此模块不需要时,删除此模块对应的文件夹,即可将此模块相关文件全部移除;
- 文件夹命名:小写英文+连字符(减号),比如:
account-manage
; - 文件命名: 驼峰式命名,首字母大写:比如
AccountManage.jsx
;一个文件一个类,而且文件名和类名必须完全一致,默认export类名(或者变量名)与文件名完全一致。 添加修改页面,文件名以Edit结尾,列表页面,文件名以List结尾,详情页面以Detail结尾;
1
2
3AccountEdit.jsx
AccountDetail.jsx
AccountList.jsxcss/less命名:一个模块下基本就包含一个css/less文件,命名为style.css/style.less即可;
- 图片:小写英文+连字符(减号),比如:
user-avatar.jpg
- 文件之间的依赖,统一使用ES6写法:
import request from 'xxx.jsx'
; - 统一使用ES6得模块写法(
import
,export
),不要使用其他方式。
jsx
文件名必须和默认输出完全保持一致
1
2
3
4
5
6
7
8// file CheckBox.js or CheckBox.jsx
class CheckBox {
// ...
}
export default CheckBox;
// good
import CheckBox from './CheckBox';import必须写在文件的头部,未使用到的引入,要删除。
- export必须写在文件底部,通过export {aaa,bbb,Ccc as ccc }方式导出多个变量,通过export default aaa 导出默认变量。
import各类型文件顺序
- css/less文件
- 第三方模块
- 自定义模块
- 图片
- 声明模块变量
比如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50// css/less文件
import './style.less';
//第三方模块
import React from 'react';
import {Link} from 'react-router'
import assign from 'object-assign';
import moment from 'moment';
import {message, Button, Row, Col, Tabs, Progress } from 'antd'
//自定义模块
import Page from '../../framework/page/Page';
import ajax from '../../framework/common/ajax'
//图片
import UserAvatar from './user-avatar.jpg'
// 模块变量
const TabPane = Tabs.TabPane;
const ProgressLine = Progress.Line;
//或者这样:
// css/less文件
import './style.less';
//第三方模块
import React from 'react';
import {Link} from 'react-router'
import assign from 'object-assign';
import moment from 'moment';
//自定义模块
import Page from '../../framework/page/Page';
import ajax from '../../framework/common/ajax'
//图片
import UserAvatar from './user-avatar.jpg'
//一次性引入过多,最好使用如下方式,方便增,删
import {
message,
Button,
Row,
Col,
Tabs,
Form,
Modal,
Input,
InputNumber,
DatePicker,
Radio,
Checkbox,//保留这个逗号,方便增,删
} from 'antd'
// 模块变量
const TabPane = Tabs.TabPane;
const ProgressLine = Progress.Line;声明引用一个第三方模块的变量,必须使用const
1
2const TabPane = Tabs.TabPane;
const ProgressLine = Progress.Line;尽量使用
const
声明变量,其次使用let
,不允许使用var
React统一使用ES6写法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31// 是否考虑创建一个BaseComponent,其他类继承BaseComponent?
// BaseComponent中可以封装一些常用方法。
class App extends React.Component{
// 构造函数
constructor(props){
super(props);
}
// 初始化state,替代原getInitialState, 注意前面没有static
state = {
showMenu:false
};
// 替代原propTypes,指定props参数规范, 属性,注意前面有static,属于静态方法.
static propTypes = {
autoPlay: React.PropTypes.bool.isRequired
}
// 默认defaultProps,替代原getDefaultProps方法, 注意前面有static,属于静态方法.
static defaultProps = {
loading:false
};
componentDidMount() {
// do something yourself...
}
// 事件的写法,这里要使用箭头函数,箭头函数不会改变this的指向,否则函数内,this指的就不是当前对象了
// React.CreatClass方式React会自动绑定this,ES6写法不会.
handleClick = (e)=>{
this.setState();//这里的this指的还是App
};
render(){
}
}jsx类的结构顺序:
- constructor
- state
- static propTypes
- static defaultProps
- 其他自定义属性或静态(类)属性
- 周期函数componentDidMount等
- 自定义函数handle系列等
- 其他自定义辅助函数
- render
遵循这样的约定,方便快速查找各部分代码。
jsx中事件属性,统一on开头,比如
1
<Sidebar onClick={this.handleClick} onToggle={this.handleToggle}></Sidebar>
事件处理函数命名,统一
handle
开头,驼峰式命名,比如:handleClick
handleToggle
等事件统一使用箭头函数,箭头行数不会改变向上文(
this
指向),不必使用bind
了。1
2
3handleClick = (e) => {
// Do something here!
};请求统一使用封装过的request
- 提示信息统一使用 src/common.jsx/MESSAGE_CONTENT中维护的内容。
1
2
3
4
5
6
7// 变量命名 取名字比较费劲 可读性较好
exports const MESSAGE_CONTENT = {
OPERATE_SUCCESS:'操作成功',
OPERATE_FAILED:'操作失败',
LOGIN_SUCCESS:'登陆成功',
STORE_NAME_CAN_NOT_BE_NULL:'门店不能为空'
}
less/css
- 每个模块如果只有一个less/css文件,要命名为
style.less/style.css
- 类名/id名 小写英文+连字符,比如:
.user-avatar
各个模块的样式,以一个大的父级开始写起,避免各个模块样式冲突
1
2
3
4
5
6
7
8.account-manage{
.block{
...
}
#some-id{
...
}
}编写less时,避免嵌套多层(最多不要超过3层)。不要编写太过于复杂的less。
路由结构规范
特殊情况,不能按照规范实现,与各位leader商榷1
2
3
4/m/1 对应商户 1 为商户id
/s/2 对应门店 2 为门店id
多单词使用“_”链接,不要使用“-”,或其他特殊字符。
根据菜单结构,定义url结构,RestFull 约定,具体看下面例子。
例如:
菜单结构:1
2
3品牌
-门店
-门店管理
对应的菜单为1
2
3
4
5
6
7
8列表页:
http:localhost:8080/m/1/stores
详情页
http:localhost:8080/m/1/stores/12
添加页
http:localhost:8080/m/1/stores/new
修改页
http:localhost:8080/m/1/stores/12/edit
菜单结构1
2
3
4
5门店 # store
-订单 # order 一级
-外卖订单 # take_out 二级
-新订单 # new_order 可点击跳转页面
-所有订单 # all_order 可点击跳转页面
对应的菜单为:1
2
3
4
5
6
7
8列表页
http:localhost:8080/m/1/s/2/order/take_out/new_orders
详情页
http:localhost:8080/m/1/s/2/order/take_out/new_orders/12
添加页
http:localhost:8080/m/1/s/2/order/take_out/new_orders/new
修改页
http:localhost:8080/m/1/s/2/order/take_out/new_orders/21/edit
未完待续