部分代码规范

203 阅读3分钟
  1. 代码格式化

    eslint、prettier

    js 中使用单引号 ''、html 中使用双引号 "" 判断语句 === 代替 == 属性命名 -- 驼峰式 对象中键值对间 : 前无空,后空格

  2. 组件拆分

    一个大的业务组件,尽量差分多个子组件,组件代码简短,便于查看、理解及后续维护。可复用的组件应拆分到 src/components(小标题、导出到Excel、下拉选择器等),否则拆分到当前路径下 components(列表页的表单与数据列表) UI组件

  3. immutable 使用

    shouldComponentUpdate(nextProps, nextState) 组件判断是否重新渲染时调用,我们可以在 shouldComponentUpdate() 中使用 deepCopy 和 deepCompare 来避免无必要的 render(),但 深拷贝 和 深比较 一般都是非常耗性能的。

    immutable 提供了简洁高效的判断数据是否变化的方法,只需 === 和 is 比较就能知道是否需要执行 render(),而这个操作几乎 0 成本,所以可以极大提高性能。推荐 使用,可以避免不必要的、重复的组件渲染,从而提高性能。

    shouldComponentUpdate(nextProps, nextState) {
        return (
            !is(fromJS(this.props), fromJS(nextProps))|| !is(fromJS(this.state), fromJS(nextState))
        );
    }
    
  4. 注释格式

    • 变量 或 参数注释 -- 类似以下说明
    constructor(props) {
        super(props);
        this.state = {
            statejudgment: false, // **状态判断
        }
    }
    
    // 角色信息数组
    let roles = [];
    
    • 方法 或 函数注释 -- method、return、param、Description
    /**
     * @method 修改***信息
     * @return {Type}
     * @param {String} value 更改的值
     * @description 其他需要的详细说明(条件或场景)
    */
    handleChange(value) {
        // ...
    }
    
    // 保存数据
    handleClickSave() {
        // ...
    }
    
    • 组件注释 -- Author、Date、Modified by or time、Description
    /*
     * @Author: wqjiao
     * @Date: 2019-03-15 13:45:30
     * @Last Modified by:   wqjiao
     * @Last Modified time: 2019-03-15 13:45:30
     * @Description: HelpCenter 帮助中心
    */
    export default class HelpCenter extends Component {
        render() {
            return (<div></div>)
        }
    }
    
  5. 声明多个变量

    在 js 代码中会出现声明多个变量的情况,此时可以使用一个 let/var 语句来同时声明多个变量,以减少整个脚本的执行时间,且代码格式也相对规范。

    // bad
    let a = 1;
    let b = 2;
    let c = 3;
    
    // good
    let a = 1,
        b = 2,
        c = 3;
    
  6. 组件中使用到的 state,应保证在 constructor 中定义

    // bad
    constructor(props) {
        super(props);
    }
    componentDidMount() {
        me.setState({
            name: 'wqjiao' // name 应在 constructor 中定义
        });
    }
    
    // good
    constructor(props) {
        super(props);
        this.state = {
            name: '' // 收件人姓名
        }
    }
    componentDidMount() {
        me.setState({
            name: 'wqjiao' // name 应在 constructor 中定义
        });
    }
    
  7. 一个方法或流程中能使用一次 setState({}) 参数的,就避免使用多次 setState({}) 设置 state

    constructor(props) {
        super(props);
        this.state = {
            a: 1,
            b: 2
        }
    }
    
    // bad
    handleClick(isShow, title, data) {
        let me = this;
        let newState = Object.assign(me.state, {
            a: data.a,
            b: data.b,
            c: data.c
        });
    
        // 1
        me.setState(newState);
    
        // 2
        me.setState({
            visible: isShow
        });
    
        // 3
        if (title) {
            me.setState({title});
        }
    }
    
    // good
    handleClick(isShow, title, data) {
        let me = this,
            newState = Object.assign(me.state, {
                a: data.a,
                b: data.b,
                c: data.c
            });
    
        me.setState({
            ...newState,
            visible: isShow,
            title: title || me.state.title
        });
    }
    
  8. 尽量减少使用 refs

    采用回调或其他方式代替,避免操作时组件 没有实例化undefined,页面报错

  9. 项目中的路由比较多时,按照代码拆分 asyncComponent() 按需加载组件,路由引入可按照业务分类

  10. 在非业务组件中避免使用 redux(mapStateToPropsmapDispatchToProps) 通过 props 传递数据

  11. 多层判断时,做到可以提前返回的尽量先返回,避免多层包裹

    function (str) {
        if (!str) {
            // do something
            return '没有值';
        }
        
        // do something
        return '有值';
    }
    
  12. $.extend() 和 Object.assign() 复制对象到目标对象

    • $.extend() 是 jQuery 的方法
    • Object.assign(target, sources) 原生 javascript 方法 target 目标对象 sources 源对象 返回值 -- 目标对象
    • ES6 语法,扩展语法