当前位置: 首页 > news >正文

Ant Design ProTable组件深度解析

目录

一、Mock 数据服务 (mock.ts)

二、ProTable 组件 (ProTableWithModal.tsx)

三、关键特性说明

四、技术栈关系图


以下是对基于 Ant Design Pro v6 (TypeScript) 的 ProTable 组件的分析,包含代码注释和关键功能说明:


一、Mock 数据服务 (mock.ts)

// 模拟数据源(内存数据库)
import type { Request, Response } from 'express';
const dataSource: any[] = [{id: '1',name: '初始数据',description: '系统初始数据',status: 'active',createTime: '2025-07-10T08:30:00Z'}
];// RESTful API 模拟
export default {// GET /api/data 分页查询'GET /api/data': (req: Request, res: Response) => {// 1. 解析查询参数const page = parseInt(req.query.page as string) || 1; // 当前页码const pageSize = parseInt(req.query.pageSize as string) || 5; // 页大小const { name, status } = req.query; // 搜索条件// 2. 过滤逻辑(按名称/状态)let filteredData = [...dataSource]; // 复制原始数据if (name) filteredData = filteredData.filter(item => item.name.includes(name));if (status) filteredData = filteredData.filter(item => item.status === status);// 3. 分页处理 (slice实现)const start = (page - 1) * pageSize;const pageData = filteredData.slice(start, start + pageSize);// 4. 返回标准响应格式res.send({success: true,data: pageData,     // 当前页数据total: filteredData.length // 总记录数});},// POST /api/data 创建数据'POST /api/data': (req: Request, res: Response) => {const newItem = {...req.body,   // 接收请求体数据id: `id-${Date.now()}`,    // 生成唯一IDcreateTime: new Date().toISOString() // 创建时间};dataSource.push(newItem); // 添加到数据源res.send({ success: true, data: newItem }); // 返回新建项},
// 更新数据'PUT /api/data/:id': (req: Request, res: Response) => {const { id } = req.params;const index = dataSource.findIndex(item => item.id === id);if (index !== -1) {dataSource[index] = { ...dataSource[index], ...req.body };res.send({ success: true });} else {res.status(404).send({ success: false, message: '数据未找到' });}},// 删除数据'DELETE /api/data/:id': (req: Request, res: Response) => {const { id } = req.params;const index = dataSource.findIndex(item => item.id === id);if (index !== -1) {dataSource.splice(index, 1);res.send({ success: true });} else {res.status(404).send({ success: false, message: '数据未找到' });}}
};

关键说明​:

  1. 使用内存数组 dataSource 模拟数据库
  2. 实现 RESTful 接口规范:
    • GET:分页查询 + 过滤
    • POST:创建资源
    • PUT:更新资源(通过ID定位)
    • DELETE:删除资源
  3. 分页逻辑:slice(start, start+pageSize) 实现内存分页
  4. 响应格式:标准 {success, data, total} 结构

二、ProTable 组件 (ProTableWithModal.tsx)

import React, { useRef, useState } from 'react';
import { PlusOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons';
import { Button, Form, Input, Modal, Select, message, Popconfirm } from 'antd';
import { ProTable } from '@ant-design/pro-components';
import type { ActionType, ProColumns, ProFormInstance } from '@ant-design/pro-components';
import { request } from 'umi';// 定义数据类型
interface FormValues {name: string;description: string;status?: string;
}interface DataItem extends FormValues {id: string;createTime: string;
}const ProTableWithModal: React.FC = () => {const [form] = Form.useForm<FormValues>();const searchFormRef = useRef<ProFormInstance>();const [visible, setVisible] = useState(false);const [editingRecord, setEditingRecord] = useState<DataItem | null>(null);const actionRef = useRef<ActionType>();// 状态枚举值const statusEnum = {active: { text: '启用', status: 'Success' },inactive: { text: '停用', status: 'Error' },};// 处理编辑操作const handleEdit = (record: DataItem) => {setEditingRecord(record);form.setFieldsValue({name: record.name,description: record.description,status: record.status});setVisible(true);};// 处理删除操作const handleDelete = async (id: string) => {try {const response = await request(`/api/data/${id}`, {method: 'DELETE'});if (response.success) {message.success('删除成功');actionRef.current?.reload();}} catch (error) {message.error('删除失败');}};// 处理表格请求(带分页和搜索)const handleRequest = async (params: any & {pageSize?: number;current?: number;keyword?: string;}) => {const { current, pageSize, ...filters } = params;try {const response = await request('/api/data', {method: 'GET',params: {...filters,page: current,pageSize}});const tableData = Array.isArray(response.data)? response.data: response.data?.list || [];return {data: tableData,success: true,total: response.total,};} catch (error) {return {data: [],success: false,total: 0};}};// 表单提交处理(添加/编辑)const handleSubmit = async (values: FormValues) => {try {const method = editingRecord ? 'PUT' : 'POST';const url = editingRecord ? `/api/data/${editingRecord.id}` : '/api/data';const response = await request(url, {method,data: {...values,...(editingRecord ? {} : {id: `id-${Date.now()}`,createTime: new Date().toISOString()})}});if (response.success) {message.success(editingRecord ? '更新成功' : '添加成功');actionRef.current?.reload();setVisible(false);form.resetFields();setEditingRecord(null);}} catch (error) {message.error('操作失败');}};// 重置功能const handleReset = () => {if (searchFormRef.current) {searchFormRef.current.resetFields();}actionRef.current?.reset?.();actionRef.current?.reload();};// 表格列配置const columns: ProColumns<DataItem>[] = [{title: '名称',dataIndex: 'name',width: 120,search: true,fieldProps: { placeholder: '请输入名称搜索' },},{title: '描述',dataIndex: 'description',search: false,ellipsis: true,},{title: '状态',dataIndex: 'status',valueType: 'select',valueEnum: statusEnum,initialValue: 'active',search: {transform: (value) => ({ status: value }),},},{title: '创建时间',dataIndex: 'createTime',valueType: 'dateTime',hideInSearch: true,},{title: '操作',valueType: 'option',render: (_, record) => [<Buttonkey="edit"type="link"icon={<EditOutlined />}onClick={() => handleEdit(record)}/>,<Popconfirmkey="delete"title="确定要删除吗?"onConfirm={() => handleDelete(record.id)}><Button type="link" danger icon={<DeleteOutlined />} /></Popconfirm>],},];return (<div style={{ padding: 24 }}><ProTable<DataItem>actionRef={actionRef}formRef={searchFormRef}columns={columns}rowKey="id"pagination={{ pageSize: 5 }}request={handleRequest}toolBarRender={() => [<Buttonkey="add"type="primary"icon={<PlusOutlined />}onClick={() => {setEditingRecord(null);setVisible(true);}}>新建条目</Button>,]}search={{optionRender: (_, __, dom) => [...dom,<Buttonkey="global-reset"onClick={handleReset}style={{ marginLeft: 8 }}>全局重置</Button>]}}/>{/* 弹窗表单 */}<Modaltitle={editingRecord ? "编辑数据" : "添加新数据"}open={visible}onCancel={() => {setVisible(false);form.resetFields();setEditingRecord(null);}}onOk={() => form.submit()}destroyOnClose><Formform={form}layout="vertical"onFinish={handleSubmit}initialValues={{ status: 'active' }}><Form.Itemlabel="名称"name="name"rules={[{ required: true, message: '请输入名称' }]}><Input placeholder="请输入名称" /></Form.Item><Form.Itemlabel="描述"name="description"rules={[{ max: 100, message: '不超过100字符' }]}><Input.TextArea placeholder="请输入描述" rows={3} /></Form.Item><Form.Itemlabel="状态"name="status"><Select options={[{ value: 'active', label: '启用' },{ value: 'inactive', label: '停用' }]} /></Form.Item></Form></Modal></div>);
};export default ProTableWithModal;

三、关键特性说明

  1. ProTable 核心功能​:

    • 自动分页​:通过 request 属性绑定数据获取函数
    • 搜索集成​:search: true 开启列搜索
    • 值枚举映射​:valueEnum 实现状态→标签的转换
  2. Umi Request 使用​:

    // 统一请求方法
    request('/api/data', {method: 'GET',params: { page: 1, name: 'test' }
    });
    • 内置错误处理
    • 自动处理 loading 状态
  3. 表单管理最佳实践​:

    • 使用 Form.useForm() 管理表单状态
    • form.setFieldsValue() 实现数据回填
    • destroyOnClose 保证弹窗关闭时重置状态
  4. 全局重置功能​:

    const handleReset = () => {searchFormRef.current?.resetFields(); // 重置搜索表单actionRef.current?.reload();           // 重置表格数据
    };

四、技术栈关系图

此实现完整展示了 CRUD 操作的现代前端架构,结合了 Ant Design Pro 的 UI 组件能力和 Umi 的工程化优势,适合作为中后台系统的模板代码。

http://www.dtcms.com/a/274690.html

相关文章:

  • CUDA —— 2.3、cuda静态全局变量__device__使用介绍(附:完整代码)
  • 系统思考:多元胜过能力
  • 计算机网络第三章(5)——数据链路层《广域网》
  • 解锁形状与空间的奥秘:微分几何与流形一瞥-AI云计算拓展核心内容
  • 【C++篇】二叉树进阶(上篇):二叉搜索树
  • 云蝠智能 VoiceAgent重构企业呼入场景服务范式
  • Ubuntu20.04运行openmvg和openmvs实现三维重建(未成功,仅供参考)
  • PyTorch笔记5----------Autograd、nn库
  • 《棒球规则介绍》领队和主教练谁说了算·棒球1号位
  • sqli-labs靶场通关笔记:第1-4关 联合注入
  • ros topic和service的使用
  • 深入浅出Redis:一文掌握Redis底层数据结构与实现原理
  • Java Stream流介绍及使用指南
  • GIC控制器 (三)
  • 猿人学js逆向比赛第一届第十八题
  • 【一起来学AI大模型】微调技术:LoRA(Low-Rank Adaptation) 的实战应用
  • Linux kernel regcache_cache_only()函数详解
  • pytest中mark的使用
  • SpringCloud之Feign
  • 深入探讨大模型的记忆机制及其前沿技术
  • 数据结构与算法——从递归入手一维动态规划【2】
  • 极端高温下的智慧出行:危险检测与救援
  • AI介入电商内容生产,会颠覆品牌运营吗?
  • 打破内网壁垒,轻松实现安防视频的云端汇聚与P2P超低延迟播放
  • 史上最详细Java并发多线程(面试必备,一篇足矣)
  • 进制转换小题
  • 5 大人工智能知识管理工具
  • 冒泡排序和快速排序
  • 云成本优化完整指南:从理论到实践的全方位解决方案
  • 聚焦数据资源建设与应用,浙江省质科院赴景联文科技调研交流