【React 】基于Antd Design的RadioGroup按钮组控件封装

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Weixiaohuai/article/details/88243990

一、简介

基于项目中大量使用到需要动态查询数据库,然后动态渲染RadioGroup组件,于是对Radio.Group进行了封装,主要有以下几点功能:

【a】通过配置数据源标识,结合后端接口,可以动态查询出需要的单选按钮组数据出来,约定以'DMK_'加上对应代码库标识,如: sign={'DMK_WJCF_WJLX'},简单理解就是对应数据库中的查询标志;

【b】支持自定义数据源Options, 使用自定义数据源时,需注意格式. 如: [{"VALUE":"1","LABEL":"日常违纪"},{"VALUE":"2","LABEL":"考试违纪"},{"VALUE":"3","LABEL":"公寓违纪"}];

【c】支持动态设置按钮组中的哪些按钮启用或禁用状态,使用radioDisabledArr属性可动态配置需要禁用的按钮VALUE值,如: radioDisabledArr={['2','3']};

【d】支持数据过滤功能,有些情况下需要动态控制哪些按钮需要展示哪些需要隐藏,使用filterType集合filterData可以过滤指定按钮, 如: filterType={'save'} filterData={['2', '3', '4']};

配置示例:

<NHRadioGroup
       onChange={this.onWjlxChangeListener}
       radioStyle={radioStyle}
       sign={'DMK_WJCF_WJLX'}
       radioGroupDisabled={false}
       radioDisabledArr={['1', '2']}
       filterType={'save'}
       filterData={['2', '3', '4']}

二、组件代码NHRadioGroup.js

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

const RadioGroup = Radio.Group;

const pathUrl = "/proData/selectDataList";

/**
 * @Description: 单选按钮组控件
 * @author weishihuai
 * @date 2019/3/6 15:06
 *
 * 使用说明:
 * 1. 使用sign标识从后台查询数据源时,以'DMK_'加上对应代码库标识,如: sign={'DMK_WJCF_WJLX'}
 * 2. 使用自定义数据源时,需注意格式. 如: [{"VALUE":"1","LABEL":"日常违纪"},{"VALUE":"2","LABEL":"考试违纪"},{"VALUE":"3","LABEL":"公寓违纪"}]
 * 3. 使用radioDisabledArr属性可动态配置需要禁用的按钮VALUE值,如: radioDisabledArr={['2','3']}
 * 4. 使用filterType集合filterData可以过滤指定按钮, 如: filterType={'save'} filterData={['2', '3', '4']}
 * 5. 使用示例:
 * <NHRadioGroup
 *      onChange={this.onWjlxChangeListener}
 *      radioStyle={radioStyle}
 *      sign={'DMK_WJCF_WJLX'}
 *      radioGroupDisabled={false}
 *      radioDisabledArr={['1', '2']}
 *      filterType={'save'}
 *      filterData={['2', '3', '4']}
 * />
 *
 */
class NHRadioGroup extends React.Component {

    constructor(props) {
        super(props);
        const {value = ''} = this.props;
        this.state = {
            data: [],
            value: value
        }
    }

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

    UNSAFE_componentWillReceiveProps(nextProps) {
        if ('value' in nextProps) {
            const value = nextProps.value;
            this.setState({
                value: value
            });
        }
        if ('dataSource' in nextProps) {
            const dataSource = nextProps.dataSource;
            this.setState({
                data: dataSource
            });
        }
    }

    //根据数据源标识从后台查询DataSource
    getDataSource = (sign) => {
        if (!sign) {
            this.getCustomDataSource();
        } else {
            NHFetch(pathUrl, 'GET', {sign: sign})
                .then(res => {
                    if (res) {
                        let data = res.data;
                        if (data) {
                            this.setState({
                                data: [...data]
                            });
                        } else {
                            this.getCustomDataSource();
                        }
                    }
                });
        }
    };

    //使用自定义的DataSource
    getCustomDataSource = () => {
        const {dataSource = []} = this.props;
        if (dataSource && dataSource.length > 0) {
            this.setState({
                data: [...dataSource]
            });
        }
    };

    //选项变化时的回调函数
    onRadioSelectChange = (e) => {
        const {onChange} = this.props;
        if (onChange && typeof onChange === 'function') {
            onChange(e.target.value);
        }
    };

    //检查单选按钮是否需要禁用
    checkRadioIsDisable = (radioDisabledArr, value) => {
        if (radioDisabledArr && radioDisabledArr.length <= 0) {
            return false;
        }
        let val = radioDisabledArr.find((key) => {
            return value === key || value === key
        });
        return val !== undefined;
    };

    //组装Radio Options
    buildRadioOptions = (filteredData, radioStyle, radioDisabledArr) => {
        return filteredData.map(option => <Radio style={radioStyle}
                                                 key={option.VALUE || option.value}
                                                 disabled={this.checkRadioIsDisable(radioDisabledArr, option.VALUE || option.value)}
                                                 value={option.VALUE || option.value}>{option.LABEL || option.label}</Radio>)
    };

    render() {
        const {value, data = []} = this.state;
        const {radioStyle = {}, radioGroupDisabled, defaultValue, radioDisabledArr = [], filterType = '', filterData = []} = this.props;
        let radioOptions = [];

        //同时指定过滤类型和需要过滤的数据VALUE
        if (filterType && filterData) {
            switch (filterType) {
                case 'remove': { //过滤掉指定key的单选按钮
                    let filteredData = data.filter((item) => {
                        let itemVal = item.VALUE || item.value;
                        let isExist = filterData.find((val) => {
                            return val === itemVal;
                        });
                        return isExist === undefined;
                    });
                    if (filteredData && filteredData.length > 0) {
                        radioOptions = this.buildRadioOptions(filteredData, radioStyle, radioDisabledArr);
                    }
                    break;
                }
                case 'save': { //保留指定key值的单选按钮
                    let filteredData = data.filter((item) => {
                        let itemVal = item.VALUE || item.value;
                        let isExist = filterData.find((val) => {
                            return val === itemVal;
                        });
                        return isExist !== undefined;
                    });
                    if (filteredData && filteredData.length > 0) {
                        radioOptions = this.buildRadioOptions(filteredData, radioStyle, radioDisabledArr);
                    }
                    break;
                }
                default: {
                    radioOptions = this.buildRadioOptions(data, radioStyle, radioDisabledArr);
                    break;
                }
            }
        } else {
            //不进行数据过滤
            radioOptions = this.buildRadioOptions(data, radioStyle, radioDisabledArr);
        }

        return (
            <div>
                <RadioGroup onChange={this.onRadioSelectChange} disabled={radioGroupDisabled} value={value}
                            defaultValue={defaultValue}>
                    {radioOptions}
                </RadioGroup>
            </div>
        )
    }
}

NHRadioGroup.defaultProps = {
    radioGroupDisabled: false,      //按钮组启用/禁用状态
    radioDisabledArr: [],           //需要禁用的按钮集合
    radioStyle: {},                 //按钮排列样式,可配置垂直排列,默认水平排列
};

NHRadioGroup.propTypes = {
    sign: PropTypes.string,                             //数据源标识
    dataSource: PropTypes.arrayOf(                      //自定义数据源
        PropTypes.shape({
            value: PropTypes.string,
            label: PropTypes.node
        })
    ),
    radioGroupDisabled: PropTypes.bool,                 //按钮组启用/禁用状态
    defaultValue: PropTypes.string,                     //默认值
    value: PropTypes.string,                            //初始值
    onChange: PropTypes.func,                           //选项变化时的回调函数
    radioDisabledArr: PropTypes.array,                  //需要禁用的按钮Value集合
    filterType: PropTypes.oneOf(['save', 'remove']),    //过滤数据类型,save - 保留  remove - 移除
    filterData: PropTypes.array                         //过滤数据, save - 保留指定的filterData remove - 移除指定的filterData
};

export default NHRadioGroup;

三、测试

正常如果不需要过滤数据,也不需要进行启用禁用的话, 直接使用下面的语句就行了。

<NHRadioGroup onChange={this.onWjlxChangeListener} sign={'DMK_WJCF_WJLX'}/>

猜你喜欢

转载自blog.csdn.net/Weixiaohuai/article/details/88243990