React凤凰项目规范

技术资源

基础语法

框架

组件库

构建编译

代码校验工具

代码规范

React

基础规范

  1. 统一全部采用 Es6
  2. 定义变量使用let ,定义常量使用const, 使用ESModule、避免与CommonJS 混用。
  3. 每个文件只包含的一个 React 组件(联系紧密的组件可以使用「命名空间的形式」)。
  4. 始终使用 JSX 语法,不要使用 React.createElement 创建 ReactElement,以提高编写速度、可读性、可维护性。
  5. 在传递props时,如无必要,不能传递整个props,只需传递props中所需要的属性
  6. 在组件行内设置属性,不要在外部改变属性的值;
  7. 属性较多使用 {...this.props} 语法;
  8. 重复设置属性值时,前面的值会被后面的覆盖。
  9. 自定义方法放在 React API 方法之后、.render() 之前、.render() 方法始终放在最后;
  10. 避免 this.$parent
  11. 谨慎使用 this.$refs
  12. 每个文件最好不要超过300
  13. 对待修改/优化建议使用TODO:xxx 进行高亮提示 (vscode 插件: TODO Highlight、Todo Tree)
命名规范

函数命名 (前缀为动词,名字应该明确表达函数作用)

动词 含义 举例
can 判断是否可以执行某个权限 canLogin
has 判断是否含有某个值 hasToken
is 判断是否为某个值 isShowModel
get 获取某个值 getUserId
get 设置某个值 setCookie
load 加载某些数据 loadList
update 更新某些数据 updateUserInfo
del 删除某些数据 delMenu
on/handle 组件内事件函数 onRadioChange/handleCheckButton
... ... ...

扩展名:使用 .jsx/.tsx 作为 React 组件的扩展名;文件名:使用大驼峰,如 MyComponent;

组件命名:一个目录的根组件使用 index.jsx/.tsx 命名,以目录名称作为组件名称;

// bad
import Footer from './Footer/Footer';
// bad
import Footer from './Footer/index';  
// good
import Footer from './Footer';

组件相关规范

  1. 组件声明:class App extends Component/PureComponent{}
  2. 行内迭代:使用map进行迭代、避免使用数组的index来作为属性key的值,推荐使用唯一ID
     const { options } = this.props
     return (
       <div>
         {options.map((data) =>
           <Component name={data.name} key={data.id} />
         )}
       </div>
     );
    
  3. 注释:组件之间的注释需要用 {} 包裹。
  4. 使用箭头函数进行 this 指向
     // good
     getValue = () => {}
     <MyComponent onClick = { this.getValue } />
    
  5. 对于无状态组件、使用纯函数组件而非使用 Class
编写技巧

先引用外部组件库,再引用当前组件块级组件, 然后是公共函数库最后是 css 样式

import * as React from 'react';
import { Dropdown, Menu, Icon } from 'antd';
import MyComponent from './MyComponent';
import Header from 'common/Header';
import Styles from './index.less';

解构

// good
const { name } = this.props
const { name } = this.state

// bad
this.props.name
this.state.name

每次变更state 必须调用setState方法

//good
this.setState({name:'Lucy'});

//bad
this.state.name = 'Lucy';

在State更新时,如果更新的值涉及到了state和props,调用setState时不要直接使用this.props和this.state

//good 
this.setState((prevState, props) => ({
   name: prevState.name + props.increment
}));

//bad
this.setState({name:this.state.name});

setState是异步的,若执行setState后需马上调用、创建回调函数

this.setState(
  {
    name: 'Lucy',
  },
  () => {
    // do something after state change
  },
);

尽量使用三目运算

//good
ShowUserInfo(){
    return isShowUserInfo : (<div>姓名:张三</div>) ? (<div>姓名:未填写</div>)
}

自闭合标签

  1. JSX 中所有标签必须闭合;传递默认值为true
// good
<MyComponent showName={true}/>

() 使用

  1. 多行的 JSX 使用 () 包裹,有组件嵌套时使用多行模式;
  2. 单行 JSX 省略 ()

JSX 属性使用双引号"",JS相关属性使用单引号''

// bad
<Foo bar='bar' />

// good
<Foo bar="bar" />

变量判定

  1. 对所有定义的或者传入的变量,都进行默认设置或者判定是否为undefined,防止数据未定义时程序报错。
// good 
onChange(value => console.log(value?.name))

数据操作

  1. 数组与数组合并
// good
const a = [1,2];
const b = [3,4];
const c = [...a,...b]; 
  1. 对象与对象合并
// good
const a = {name:'张三'}
const b = {age:32}
const c = {...a,...b};
  1. 对象并入数组
// good
const a = [{name:'张三'}];
const b = {name:'Lucy'};
const c = [...a,b];
  1. 数值互换
// good
let a = 1;
let b = 2;
[a,b] = [b,a];
注释规范

文件顶部的注释,包括描述、作者、日期 (vscode 插件 vscode-fileheader)

 /**
 * @Author: yushengyu 
 * @description 前端代码规范
 * @Date: 2020-05-28 16:18:10 
 * @Last Modified by: yushengyu
 * @Last Modified time: 2020-05-28 16:23:36
 **/
 

以下情况需加注释

  1. 公共组件使用说明
  2. 各组件中重要函数或者类说明
  3. 复杂的业务逻辑处理说明
  4. 特殊情况的代码处理说明,对于代码中特殊用途的变量、存在临界值、函数中使用的hack、使用了某种算法或思路等需要进行注释描述
  5. 注释块必须以/(至少两个星号)开头/;
  6. 单行注释使用//

注释块

  /**
   *@description 函数注释(做什么的)
   *@param {string} p1 参数1的说明
   *@param {string} p2 参数2的说明,比较长
   *@return 返回值描述
  **/

  getUserInfo(p1,p2) => {
    // do something
    return xxx
  }

TypeScript

  1. 使用TSLint 管理代码规范

  2. 尽量避免使用 any 定义数据类型、写好声明文件

  3. 命名

    1. 类型名使用 PascalCase
    2. 接口名前不要加 I
    3. 枚举值使用 PascalCase ( 建议使用 enum 进行枚举)
    4. 函数名使用 camelCase
    5. 属性和局部变量名使用 camelCase
    6. 私有属性名不要使用 _ 前缀
    7. 命名时尽可能地使用全名(而非缩写)
  4. TypeScript HandelBook

CSS相关规范

  1. 使用语义化、通用的命名方式(不能使用汉语拼音);
  2. 尽量使用css moudles 避免样式代码冲突、建议使用驼峰方式进行命名;
  3. 避免选择器嵌套层级过多,尽量少于 3 级;
  4. 避免选择器和 Class、ID 叠加使用;
  5. 避免使用 !important 修改样式
  6. 使用 classnames 管理同一组件上的多个className
  7. 使用less进行样式编写、避免使用多种css处理器混用

代码提交

  1. 使用 commitizen 进行代码提交 commitizen
  2. 尽量避免代码一次性提交多个变更、在完成一个组件的开发后及时进行代码提交
  3. 拉取分支进行需求开发、不要在master进行代码提交、master仅进行分支合并

创建umi项目

脚手架创建

$ mkdir myapp && cd myapp
$ yarn create umi

选择项目

Select the boilerplate type (Use arrow keys)
  ant-design-pro  - Create project with an layout-only ant-design-pro boilerplate, use together with umi block.
❯ app             - Create project with a simple boilerplate, support typescript.
  block           - Create a umi block.
  library         - Create a library with umi.
  plugin          - Create a umi plugin.

umi+dva 项目目录结构

- config 配置文件
  -config.prod 生产环境配置
  -config.dev  开发环境配置
- mock 本地mock数据
  -component  一级目录
    -index.js mock数据
- src 主目录
  - api/services  自定义接口
    - home 页面级的接口 API
      - index.js
  - assets 静态资源文件
  - components 组件 公共组件
  - layouts/index.js  全局布局
  - models/global.js  全局store
  - pages  页面目录,里面的文件即路由
      - .umi/    dev 临时目录,需添加到 .gitignore
      - .umi-production build 临时目录,会自动删除
      - document.ejs  HTML 模板
      - 404.js  404 页面    
  - utils  公共方法
  - global.css    约定的全局样式文件,自动引入,也可以用 global.less
  - global.js     可以在这里加入 polyfill
上一篇:#646 (Div. 2)B. Subsequence Hate


下一篇:cf C. Eugene and an array