react加antd封装表格单、多选组件,支持跨页选择缓存

页面效果

react加antd封装表格单、多选组件,支持跨页选择缓存_第1张图片

子组件

import React, { useState, useEffect, forwardRef, useImperativeHandle } from 'react';
import { Modal, Input, Table, Pagination, Avatar, Select } from 'antd';
import { UserOutlined } from '@ant-design/icons';
import type { TableProps, PaginationProps } from 'antd';

// 用户接口
interface User {
    id: string;
    name: string;
    avatar: string;
}


// 组件属性接口
interface UserSelectorProps {
    open: boolean;
    mode: 'single' | 'multiple';
    dataSource: T[];
    total: number;
    onCancel: () => void;
    onOk: (selectedItems: T[]) => void;
    onSearch: (searchText: string) => void;
    onPageChange: (page: number, pageSize: number) => void;
}

// 暴露给父组件的接口
export interface UserSelectorRef {
    setSelectedItems: (items: T[]) => void;
}

// 主函数
const UserSelector = forwardRef, UserSelectorProps>(
    (
        {
            open,
            onCancel,
            onOk,
            mode,
            dataSource,
            total,
            onSearch,
            onPageChange,
        },
        ref,
    ) => {
         当前选中项
        const [selectedItems, setSelectedItems] = useState([]);

        // 暴露方法给父组件
        useImperativeHandle(ref, () => ({
            setSelectedItems: (items: User[]) => {
                setSelectedItems(items);
            },
        }));

        / 搜索框
        const [searchText, setSearchText] = useState('');

        // 处理搜索框变化
        const handleSearch = (value: string) => {
            setSearchText(value);
            onSearch(value);
        };

         对话框关闭时重置选中和搜索框
        useEffect(() => {
            if (!open) {
                setSelectedItems([]);
                setSearchText('');
            }
        }, [open]);


         分页
        const [currentPage, setCurrentPage] = useState(1);
        const [pageSize, setPageSize] = useState(5);

        // 分页改变
        const handlePageChange: PaginationProps['onChange'] = (page, pageSize) => {
            setCurrentPage(page);
            setPageSize(pageSize);
            onPageChange(page, pageSize);
        };

        / 表格
        // 列配置对象
        const columns: TableProps['columns'] = [
            {
                key: 'avatar',
                render: (_, record) => (
                    
{record.avatar ? () : (} // 如果头像为空,显示默认图标 />)} {record.name}
), }, ]; // 表格行点击事件 const handleRowClick = (record: User) => { if (mode === 'single') { onOk([record]); onCancel() } else { // 判断该行是否已经选择 const isSelected = selectedItems.some(item => item.id === record.id); if (isSelected) { // 已选择,进行删除操作 setSelectedItems(selectedItems.filter(item => item.id !== record.id)); } else { // 未选择,进行添加 setSelectedItems([...selectedItems, record]); } } }; // 表格全选,全取消 const handleSelectAll = (selected: boolean) => { if (selected) { // 全选时,将当前页未选择的用户追加到已选用户列表 const newSelectedItems = [ ...selectedItems, ...dataSource.filter( item => !selectedItems.some(selectedItem => selectedItem.id === item.id), ), ]; setSelectedItems(newSelectedItems); } else { // 取消全选时,移除当前页的用户 const newSelectedItems = selectedItems.filter( item => !dataSource.some(row => row.id === item.id), ); setSelectedItems(newSelectedItems); } }; 多选框 // 监听多选框的改变 const handleSelectChange = (values: string[]) => { const newSelectedItems = selectedItems.filter(item => values.includes(item.id)); setSelectedItems(newSelectedItems); }; return ( onOk(selectedItems)} width={600} > handleSearch(e.target.value)} style={{ marginBottom: 16 }} /> {mode === 'multiple' && (