• React 下拉多选,全选/全不选功能组件


    组件名:checkbox-select

    组件截图:

    文件内容:

    src/pages/checkbox-select/index.js

    import CheckboxSelect from 'components/checkbox-select';
    
    function Page() {
        // 演示数据
        const testList = [
            { label: '#演示项目 1', value: 1 },
            { label: '#演示项目 2', value: 2 },
            { label: '#演示项目 3', value: 3 },
            { label: '#演示项目 4', value: 4 },
            { label: '#演示项目 5', value: 5 },
            { label: '#演示项目 6', value: 6 },
            { label: '#演示项目 7', value: 7 },
            { label: '#演示项目 8', value: 8 },
        ];
    
        // 选择返回数据
        const changeCallback = (data) => {
            console.log('callback data---->', data);
        };
    
        return (
            <>
                <CheckboxSelect optionsList={testList} changeCallback={changeCallback} />
            </>
        );
    }
    
    export default Page;
    View Code

    src/components/checkbox-select/index.js

    /**
     * 包含多选框的下拉列表,含全选和全不选操作
     * */
    import { useEffect, useState, useCallback, useRef } from 'react';
    import PropTypes from 'prop-types';
    import { Checkbox, Button } from 'antd';
    import 'less/components/checkbox-select/index.less';
    
    function CheckboxSelect(props) {
        const { optionsList, changeCallback } = props;
    
        const cancelBtn = useRef();
        const [showText, setShowText] = useState('全部');
        const [isActive, setIsActive] = useState(false);
        const [checkAll, setCheckAll] = useState(true);
        const [indeterminate, setIndeterminate] = useState(false);
        const [checkboxValList, setCheckboxValList] = useState([]);
        const [checkboxOldValList, setCheckboxOldValList] = useState([]);
    
        // 多选框列表被触发的时候
        const checkboxChange = (list) => {
            setCheckboxValList(list);
            setIndeterminate(!!list.length && list.length < optionsList.length);
        };
        // 确定操作
        const confirm = () => {
            setCheckboxOldValList(checkboxValList);
            setIsActive(false);
    
            // 返回最终数据
            changeCallback(checkboxValList);
    
            // 把选择的文本显示在框框内
            if (checkboxValList.length === optionsList.length) {
                setShowText('全部');
                return;
            }
            const textArr = [];
            optionsList.forEach((item1) => {
                checkboxValList.forEach((item2) => {
                    if (item1.value === item2) {
                        textArr.push(item1.label);
                    }
                });
            });
            setShowText(textArr.join(','));
        };
        // 取消操作
        const cancel = () => {
            setCheckboxValList(checkboxOldValList);
            setIsActive(false);
        };
        // 点击操作
        const toggleClick = (ev) => {
            // 阻止事件冒泡
            ev.nativeEvent.stopImmediatePropagation();
            const status = !isActive;
            setIsActive(status);
        };
    
        // 全选/全不选 操作
        const onCheckAllChange = () => {
            const status = !checkAll;
            setCheckAll(status);
    
            // 判断是全选还是全不选
            const listArr = [];
            if (status) {
                optionsList.forEach((item) => {
                    listArr.push(item.value);
                });
            }
            setCheckboxValList(listArr);
            setIndeterminate(false);
        };
    
        // 触发内容区域
        const documentEvent = () => {
            cancelBtn.current.click();
        };
    
        // 监听全选/全不选状态
        useEffect(() => {
            setCheckAll(optionsList.length === checkboxValList.length);
            setIndeterminate(!!checkboxValList.length && checkboxValList.length < optionsList.length);
        }, [checkboxValList]);
    
        // 组件卸载
        const unComponent = () => {
            // console.log('组件卸载');
            document.removeEventListener('click', documentEvent);
        };
    
        // 初始操作
        const init = useCallback(() => {
            // 设置checkbox默认全选
            const listArr = [];
            optionsList.forEach((item) => {
                listArr.push(item.value);
            });
            setCheckboxValList(listArr);
            setCheckboxOldValList(listArr);
            // 空白文档处被点击
            document.addEventListener('click', documentEvent);
        }, []);
    
        useEffect(() => {
            init();
            return unComponent;
        }, []);
    
        return (
            <>
                <div className={`checkbox-select ${isActive ? 'checkbox-select-active' : ''}`}>
                    <div className="cs__input-wrap" onClick={toggleClick}>
                        <div className="cs__input-text">{showText}</div>
                        <span className="cs__input-icon"></span>
                    </div>
                    <div
                        className="cs__tool"
                        onClick={(ev) => {
                            ev.nativeEvent.stopImmediatePropagation();
                        }}
                    >
                        <Checkbox.Group onChange={checkboxChange} value={checkboxValList}>
                            <ul className="cs__checkbox-list">
                                {optionsList.length ? (
                                    optionsList.map((item) => {
                                        return (
                                            <li key={item.value}>
                                                <Checkbox value={item.value}>{item.label}</Checkbox>
                                            </li>
                                        );
                                    })
                                ) : (
                                    <li className="empty">暂无数据</li>
                                )}
                            </ul>
                        </Checkbox.Group>
    
                        <div className="cs__button" style={{ display: optionsList.length ? '' : 'none' }}>
                            <Checkbox indeterminate={indeterminate} onChange={onCheckAllChange} checked={checkAll}>
                                全选/全不选
                            </Checkbox>
                            <Button type="primary" size="small" onClick={confirm}>
                                确定
                            </Button>
                            <Button size="small" onClick={cancel} ref={cancelBtn}>
                                取消
                            </Button>
                        </div>
                    </div>
                </div>
            </>
        );
    }
    
    CheckboxSelect.propTypes = {
        //下拉列表数据
        optionsList: PropTypes.array,
        // 确定按钮触发返回函数:return array
        changeCallback: PropTypes.func,
    };
    
    CheckboxSelect.defaultProps = {
        optionsList: [],
    };
    
    export default CheckboxSelect;
    View Code

    src/less/components/checkbox-select/index.less

    * {
        padding: 0;
        margin: 0;
        list-style: none;
    }
    
    // --------------------------------------- 组件样式开始 ---------------------------------
    @keyframes fadeIn {
        0% {
            opacity: 0;
        }
        100% {
            opacity: 1;
        }
    }
    
    .checkbox-select {
        margin: 0px auto;
        top: 100px;
    
        max-width: 260px;
        position: relative;
        .cs__input-wrap {
            position: relative;
            cursor: pointer;
            .cs__input-text {
                width: 100%;
                padding: 0 30px 0 10px;
                height: 34px;
                line-height: 34px;
                border: 1px solid #ddd;
                user-select: none;
                white-space: nowrap;
                text-overflow: ellipsis;
                overflow: hidden;
            }
            .cs__input-icon {
                position: absolute;
                display: block;
                right: 1px;
                top: 1px;
                height: 32px;
                width: 30px;
                &::after {
                    content: ' ';
                    display: block;
                    width: 0;
                    height: 0;
                    border-left: 5px solid transparent;
                    border-right: 5px solid transparent;
                    border-top: 8px solid #555;
                    position: absolute;
                    left: 50%;
                    top: 50%;
                    transform: translate(-50%, -50%);
                }
            }
        }
        .cs__tool {
            display: none;
            position: absolute;
            width: 100%;
            left: 0;
            top: 34px;
            background-color: #fff;
            border: 1px solid #f1f1ff;
            animation: fadeIn 0.5s 0s;
            .cs__checkbox-list {
                margin-bottom: 0;
                max-height: 200px;
                overflow: hidden auto;
                label {
                    padding: 5px 10px;
                    &:hover {
                        background-color: #f1f1f1;
                    }
                }
                .ant-checkbox-wrapper {
                    width: 100%;
                }
                .empty {
                    text-align: center;
                    min-height: 100px;
                    line-height: 100px;
                    font-size: 12px;
                    color: #999;
                }
            }
    
            .ant-checkbox-group {
                padding-top: 5px;
                width: 100%;
            }
            .cs__button {
                width: 100%;
                border-top: 1px solid #f1f1f1;
                padding: 5px 10px;
                display: inline-block;
                label {
                    font-size: 12px;
                    user-select: none;
                    color: #555;
                }
                button {
                    margin: 0 5px;
                    float: right;
                }
                .ant-btn-primary {
                    margin-right: 0;
                }
            }
        }
    }
    .checkbox-select-active {
        .cs__tool {
            display: block;
        }
    }
    View Code
  • 相关阅读:
    在SharePoint中实现Workflow(2):创建一个Workflow
    pku1384PiggyBank(动态规划)
    pku1088滑雪(记忆性搜索)
    hdu1251统计难题(初次接触字典树)
    详细解说 STL 排序(Sort)
    pku1631Bridging signals(动态规划题+二分搜索)
    pku1157LITTLE SHOP OF FLOWERS(简单动态规划题:摆放鲜花使审美价值达到最高)
    pku1067取石子游戏(博弈)
    pku2524Ubiquitous Religions(初次接触并查集)
    pku1050To the Max(求矩阵的最大子段和)
  • 原文地址:https://www.cnblogs.com/zion0707/p/13962615.html
Copyright © 2020-2023  润新知