一、简介

最近在忙着开发十几个微服务,苦逼的我们前后端都要自己写,基于项目中有不少需要根据代码库常量来定制switch开关选择器的需求,所以抽了一点时间对ant design的开关选择器进行了二次封装,减少项目组成员的重复劳动。因为switch只有两种状态,所以事先约定好了只能对应代码库中常量值 ‘1’ 和 ‘0’ 。

主要有以下一些功能:

【a】可直接使用数据库常量表的标识,使用sign标识从后台查询数据源时,以'DMK_'加上对应代码库标识,如: sign={'DMK_XTGL_SFM'},可动态渲染出数据库中定义的两种状态;

【b】可以使用dataSource自定义数据源,格式如: [{"VALUE":"1","LABEL":"是"},{"VALUE":"0","LABEL":"否"}];

【c】可以使用checkedChildren/unCheckedChildren指定选中/未选中时文本;

注意: 如果同时配置了sign/dataSource/(checkedChildren/unCheckedChildren),文本取值优先级顺序: sign > dataSource > (checkedChildren/unCheckedChildren)

【d】父组件回调方法:onChange = (checked,value) => { }  : checked表示是否选中boolean值(true/false), value表示当前选择器的值('1'/'0');

 

二、NHSwitch.js

import React from "react";
import PropTypes from "prop-types";
import {Switch} from 'antd';
import NHFetch from "../../utils/NHFetch";

const pathUrl = "/proData/selectDataList";

/**
 * @Description: 开关选择器
 * @author weishihuai
 * @date 2019/3/7 9:13
 *
 * 使用说明:
 * 1. 使用sign标识从后台查询数据源时,以'DMK_'加上对应代码库标识,如: sign={'DMK_XTGL_SFM'};
 * 2. 可使用dataSource自定义数据源,格式如: [{"VALUE":"1","LABEL":"是"},{"VALUE":"0","LABEL":"否"}];
 * 3. 可以使用checkedChildren/unCheckedChildren指定选中/未选中时文本;
 *  注意: 如果同时配置了sign/dataSource/(checkedChildren/unCheckedChildren),文本取值优先级顺序: sign > dataSource > (checkedChildren/unCheckedChildren)
 * 4. onChange = (checked,value)父组件回调方法 : checked表示是否选中boolean值(true/false), value表示当前选择器的值('1'/'0');
 * 5. 使用示例:
 * <NHSwitch
 *      onChange={this.onSwitchChange}
 *      loading={false}
 *      disabled={false}
 *      size={'default'}
 *      sign={'DMK_XTGL_SFM'}
 *      dataSource={[{"VALUE":"1","LABEL":"是"},{"VALUE":"0","LABEL":"否"}]}
 *      checkedChildren={'启用'}
 *      unCheckedChildren={'禁用'}
 *      onClick={this.onClick}/>
 */
class NHSwitch extends React.Component {

    constructor(props) {
        super(props);
        const {checkedChildren = '', unCheckedChildren = '', checked} = this.props;
        this.state = {
            checkedChildren: checkedChildren,       //选中时文本
            unCheckedChildren: unCheckedChildren,   //未选中文本
            currentValue: '',                       //当前选中的值
            checked: checked,                       //当前选中状态
        };
    }

    componentDidMount() {
        const {sign} = this.props;
        this.getDataSource(sign);
    }

    UNSAFE_componentWillReceiveProps(nextProps) {
        if ('dataSource' in nextProps) {
            const dataSource = nextProps.dataSource;
            if (dataSource && dataSource.length > 0) {
                this.buildCheckedChildren(dataSource);
            }
        }
    }

    getPropsCheckedText = () => {
        const {checkedChildren = '', unCheckedChildren = ''} = this.props;
        this.setState({
            checkedChildren: checkedChildren,
            unCheckedChildren: unCheckedChildren,
        });
    };

    //加载数据源
    getDataSource = (sign) => {
        if (sign) {
            NHFetch(pathUrl, 'GET', {sign: sign})
                .then(res => {
                    if (res) {
                        let data = res.data;
                        if (data) {
                            this.buildCheckedChildren(data);
                        } else {
                            this.getCustomDataSource();
                        }
                    }
                });
        } else {
            this.getCustomDataSource();
        }
    };

    //使用自定义数据源
    getCustomDataSource = () => {
        const {dataSource = []} = this.props;
        if (dataSource && dataSource.length > 0) {
            this.buildCheckedChildren(dataSource);
        } else {
            this.getPropsCheckedText();
        }
    };

    buildCheckedChildren = (data) => {
        data.map(item => {
            let itemVal = item.VALUE || item.value;
            let itemLabel = item.LABEL || item.label;
            if (itemVal === '1') {
                this.setState({
                    checkedChildren: itemLabel,
                });
            } else {
                this.setState({
                    unCheckedChildren: itemLabel,
                });
            }
        });
    };

    //值改变回调方法
    onSwitchChange = (checked) => {
        const {onChange} = this.props;
        this.setState({
            currentValue: checked ? '1' : '0',
            checked: checked
        }, () => {
            if (onChange && typeof onChange === 'function') {
                onChange(checked, this.state.currentValue);
            }
        });
    };

    //点击事件回调方法
    onSwitchClick = (checked) => {
        const {onClick} = this.props;
        this.setState({
            currentValue: checked ? '1' : '0',
            checked: checked
        }, () => {
            if (onClick && typeof onClick === 'function') {
                onClick(checked, this.state.currentValue);
            }
        });
    };

    render() {
        const {checkedChildren = '', unCheckedChildren = '', checked} = this.state;
        const {defaultChecked, loading, size, disabled} = this.props;
        return (
            <div>
                <Switch defaultChecked={defaultChecked} checkedChildren={checkedChildren}
                        unCheckedChildren={unCheckedChildren}
                        loading={loading}
                        size={size}
                        checked={checked}
                        disabled={disabled}
                        onChange={this.onSwitchChange}
                        onClick={this.onSwitchClick}/>
            </div>
        )
    }
}

//默认属性
NHSwitch.defaultProps = {
    loading: false,
    size: 'default',
    disabled: false,
    onChange: () => {
    },
    onClick: () => {

    }
};

//属性检查
NHSwitch.propTypes = {
    sign: PropTypes.string,                 //数据源标识
    onChange: PropTypes.func,               //变化时回调函数
    onClick: PropTypes.func,                //点击时回调函数
    checkedChildren: PropTypes.string,      //选中时的内容
    unCheckedChildren: PropTypes.string,    //未选中的内容
    defaultChecked: PropTypes.bool,         //初始是否选中
    loading: PropTypes.bool,                //加载中的开关
    disabled: PropTypes.bool,               //是否禁用
    size: PropTypes.string,                 //开关大小,可选值: default/small,默认为default
    dataSource: PropTypes.arrayOf(          //自定义数据源
        PropTypes.shape({
            value: PropTypes.string,
            label: PropTypes.node
        })
    ),
};

export default NHSwitch;

三、测试

 

一般情况下,只需要指定 sign / dataSource /(checkChildren/uncheckChildren)其中一种即可,具体根据项目中需求来定。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐