React18+Antd5+TS封装的ProTable组件

1,235 阅读3分钟

React18+Antd5+TS封装的ProTable组件

话不多说直接截图奉上

卡片表格.png

普通表格.png

为什么要做这个事情呢?

  1. 刚接触React、TS技术栈不久,以学习为目的。
  2. 公司业务使用到了这个技术栈,在基础上还要兼容卡片样式的切换,用ProComponents也要封装改造一下,感觉太臃肿了并且其他组件我也用不到(官方支持单独安装使用,但我强迫症哈哈哈),于是乎我就开始了漫长的造轮子阶段。

使用教程

1. 项目介绍

ProTable 是一个功能强大的表格组件,它可以帮助我们快速地创建和管理数据表格。ProTable 提供了丰富的配置项,可以满足各种场景的需求。

2. 查询表单配置

/** @name 自定义下拉框数据 */
export interface FieldNames {
    value?: string;
    label?: string;
    options?: string;
}

/** @name 下拉框配置 */
export interface SelectProps {
    mode?: "multiple" | "tags";
    fieldNames?: FieldNames;
    options?: DefaultOptionType[];
}

/** @name 查询表单项配置 */
export interface SearchFormColumnsProps {
    type: FormItemsType;
    label?: string;
    name?: string;
    defaultValue?: any;
    colSpan?: number;
    selectProps?: SelectProps;
}

/** @name SearchForm组件参数 */
interface Props {
    search: (data: { [key: string]: any }) => void;
    formColumns: ProTableSearchFormProps;
}

3. ProTable配置

/** @name ProTable Columns */
export type ProTableColumnsProps<T = any> = ColumnsType<T>;

/** @name ProTable 表格 */
export interface ProTableProps<T = any> extends TableProps<T> {
    /** @name 表格的className */
    tableClassName?: string;
    
    /** @name 表格的style */
    tableStyle?: CSSProperties;
    
    /** @name 查询表单 */
    searchFormColumns?: ProTableSearchFormProps;
    
    /** @name 表格的title */
    tableTitle?: ReactNode;
    
    /** @name 表格的头部 */
    headerRender?: ReactNode;
    
    /** @name 表格头部右侧自定义搜索 */
    filterRender?: ReactNode;
    
    /** @name 表格右侧操作工具 */
    tools?: ToolsProps;
    
    /** @name 请求参数,修改后会触发更新 */
    params?: any;
    
    /** @name 是否手动触发请求 */
    manualRequest?: boolean;
    
    /** @name 获取表格数据方法 */
    request?: (params: any) => Promise<any>;
    
    /** @name 自定义卡片 */
    cardRender?: (data: any) => JSX.Element | React.ReactNode;
    
    /** @name 隐藏分页 */
    hidePage?: boolean;
}

/** @name 表格操作Ref */
export interface ActionProps {
    reload: Function;
}

4. 完整调用代码

import ProTable from "@/components/ProTable";
import { ActionProps, ProTableColumnsProps, ProTableSearchFormProps } from "@/components/ProTable/interface";
import BaseCard from "@/components/ProTable/modules/BaseCard";
import { Button, Input, Space } from "antd";
import dayjs from "dayjs";
import { Key, useRef, useState } from "react";

const { Search } = Input;

const MyProTable = () => {
	const actionRef = useRef<ActionProps>(null);
	const [params, setParams] = useState<{ [key: string]: any }>({
		terms: { default: "父组件默认携带的参数" },
		sorts: { field: "timestamp", order: "desc" }
	});
	const [selectedRowKeys, setSelectedRowKeys] = useState<Key[]>([]);

	// 查询表单配置项
	const searchFormColumns: ProTableSearchFormProps = [
		{
			name: "name",
			label: "功能名称",
			type: "Input"
		},
		{
			name: "funcType",
			label: "功能类型",
			type: "Select",
			selectProps: {
				mode: "multiple",
				options: []
			}
		},
		{
			name: "timestamp",
			label: "时间",
			type: "RangePicker"
		},
		{
			name: "zhanwei1",
			label: "占位1",
			type: "InputNumber"
		},
		{
			name: "zhanwei2",
			label: "占位2",
			type: "InputNumber"
		}
	];

	// 表格数据配置项
	const columns: ProTableColumnsProps = [
		{
			key: "orderNum",
			title: "序号",
			width: 80,
			align: "center",
			render: (text, record, index) => `${index + 1}`
		},
		{
			key: "name",
			title: "功能名称",
			dataIndex: "name",
			ellipsis: true
		},
		{
			key: "id",
			title: "功能标识符",
			dataIndex: "id",
			ellipsis: true
		},
		{
			key: "funcType",
			title: "功能类型",
			dataIndex: "funcType",
			filters: [],
			filterMultiple: false,
			render: record => record?.text,
			ellipsis: true
		},
		{
			key: "timestamp",
			title: "创建时间",
			dataIndex: "timestamp",
			sorter: true,
			render: record => dayjs(record).format("YYYY-MM-DD HH:mm:ss"),
			ellipsis: true
		},
		{
			key: "desc",
			title: "描述",
			dataIndex: "desc",
			ellipsis: true
		},
		{
			key: "option",
			title: "操作",
			width: 260,
			align: "center",
			render: record => (
				<Space>
					<Button
						type="link"
						onClick={() => {
							console.log(record);
						}}
					>
						查看
					</Button>
					<Button
						type="link"
						onClick={() => {
							console.log(record);
						}}
					>
						编辑
					</Button>
					<Button
						danger
						type="link"
						onClick={() => {
							console.log(record);
							actionRef?.current?.reload();
						}}
					>
						删除
					</Button>
				</Space>
			)
		}
	];

	return (
		<>
			<ProTable
				rowKey="uuid"
				ref={actionRef}
				params={params}
				tableTitle="表格标题"
				searchFormColumns={searchFormColumns}
				headerRender={
					<Space>
						<Button type="primary">创建</Button>
						<Button
							disabled={!selectedRowKeys.length}
							danger
							type="primary"
							onClick={() => {
								console.log(selectedRowKeys);
								actionRef?.current?.reload();
							}}
						>
							批量删除
						</Button>
					</Space>
				}
				filterRender={
					<Search
						allowClear
						placeholder="请输入搜索内容"
						onSearch={(value: string) => {
							setParams(pre => {
								return { ...pre, terms: { ...pre.terms, name: value } };
							});
						}}
					/>
			}
			tools={{
				card: true,
				table: true,
				reload: true,
				setting: true
			}}
			rowSelection={{
				preserveSelectedRowKeys: true,
				onChange: (selectedRowKeys: Key[]) => {
					setSelectedRowKeys(selectedRowKeys);
				}
			}}
			columns={columns}
			request={params => {
				console.log("请求参数:", params);
				// 模拟接口请求数据
				return new Promise<any>(resolve => {
					setTimeout(() => {
						resolve({
							code: 200,
							data: {
								list: [],
								pageNum: 1,
								pageSize: 12,
								total: 8
							},
							msg: "成功"
						});
					}, 500);
				});
			}}
				cardRender={record => <BaseCard {...record} />}
			/>
		</>
	);
};

export default MyProTable;

最后

需要的可以私信我,免费不要钱哦