temp-antd
v0.0.4
Published
本文档详细介绍了项目中的两个核心组件:`DynamicForm`(动态表单组件)和 `ListTable`(列表表格组件)的使用方法、属性配置和示例代码。
Maintainers
Readme
DynamicForm 和 ListTable 组件使用文档
本文档详细介绍了项目中的两个核心组件:DynamicForm(动态表单组件)和 ListTable(列表表格组件)的使用方法、属性配置和示例代码。
一、DynamicForm 组件
1. 组件介绍
DynamicForm 是一个灵活的动态表单组件,支持多种表单项类型配置、响应式布局和折叠/展开功能。它基于 Ant Design 的 Form 组件进行封装,极大简化了复杂表单的构建过程。
2. 组件属性
| 属性名 | 类型 | 默认值 | 说明 |
|-------|------|-------|------|
| items | FormItem[] | 必填 | 表单项配置数组 |
| onSubmit | (values: Record<string, unknown>) => void | 必填 | 表单提交回调函数 |
| layout | 'inline' \| 'horizontal' \| 'vertical' | 'horizontal' | 表单项标签对齐方式 |
| onReset | () => void | 可选 | 表单重置回调函数 |
| form | FormInstance | 可选 | 外部传入的 form 实例 |
| collapsed | boolean | false | 初始折叠状态 |
| submitText | string | '提交' | 提交按钮文本 |
| resetText | string | '重置' | 重置按钮文本 |
| defaultShowCount | number | 0 | 默认显示的表单项数量 |
| labelCol | Record<string, unknown> | { span: 6 } | 标签列宽度配置 |
| wrapperCol | Record<string, unknown> | { span: 16 } | 表单项列宽度配置 |
| itemsPerRow | number | 3 | 每行显示的表单项数量 |
| onCollapseChange | (collapsed: boolean) => void | 可选 | 折叠状态变化回调 |
3. FormItem 接口定义
interface FormItem {
label: string; // 表单项标签
name: string; // 表单项字段名
type:
| "text"
| "select"
| "date"
| "number"
| "checkbox"
| "radio"
| "cascader"
| "custom"
| "remoteSelect"; // 表单项类型
props?: Record<string, unknown>; // 传递给具体组件的属性
options?: { label: string; value: string | number }[]; // 仅当 type 为 select, radio, checkbox 时使用
rules?: Record<string, unknown>[]; // 校验规则
customRender?: React.ReactNode; // 当 type 为 custom 时使用
}4. 使用示例
基础用法
import React from 'react';
import { Button } from 'antd';
import DynamicForm from './components/DynamicForm';
const MyFormPage: React.FC = () => {
// 表单项配置
const formItems = [
{
label: '姓名',
name: 'name',
type: 'text',
rules: [{ required: true, message: '请输入姓名' }]
},
{
label: '年龄',
name: 'age',
type: 'number',
props: { min: 18, max: 100 }
},
{
label: '性别',
name: 'gender',
type: 'radio',
options: [
{ label: '男', value: 'male' },
{ label: '女', value: 'female' }
]
},
{
label: '兴趣爱好',
name: 'hobbies',
type: 'checkbox',
props: { mode: 'multiple' },
options: [
{ label: '阅读', value: 'reading' },
{ label: '运动', value: 'sports' },
{ label: '音乐', value: 'music' }
]
},
{
label: '出生日期',
name: 'birthday',
type: 'date',
props: { format: 'YYYY-MM-DD' }
},
{
label: '所在城市',
name: 'city',
type: 'cascader',
options: [
{
label: '北京',
value: 'beijing',
children: [{ label: '朝阳区', value: 'chaoyang' }]
},
{
label: '上海',
value: 'shanghai',
children: [{ label: '浦东新区', value: 'pudong' }]
}
]
}
];
// 处理表单提交
const handleSubmit = (values: Record<string, unknown>) => {
console.log('表单提交数据:', values);
// 这里可以处理表单提交逻辑,如API请求等
};
return (
<div>
<h2>用户信息表单</h2>
<DynamicForm
items={formItems}
onSubmit={handleSubmit}
defaultShowCount={3} // 默认显示3个表单项,其余可折叠
itemsPerRow={2} // 每行显示2个表单项
/>
</div>
);
};
export default MyFormPage;使用自定义组件
import React from 'react';
import { Input, Rate, Slider } from 'antd';
import DynamicForm from './components/DynamicForm';
const CustomFormPage: React.FC = () => {
const formItems = [
// 其他表单项...
{
label: '评分',
name: 'rating',
type: 'custom',
customRender: <Rate />,
rules: [{ required: true, message: '请评分' }]
},
{
label: '自定义输入',
name: 'customInput',
type: 'custom',
customRender: (
<>
<Input placeholder="前缀" style={{ width: '40%', marginRight: 10 }} />
<Input placeholder="后缀" style={{ width: '40%' }} />
</>
)
}
];
const handleSubmit = (values: Record<string, unknown>) => {
console.log('提交数据:', values);
};
return (
<DynamicForm
items={formItems}
onSubmit={handleSubmit}
/>
);
};二、ListTable 组件
1. 组件介绍
ListTable 是一个功能强大的列表表格组件,整合了数据展示、分页、搜索和工具栏等功能。它基于 Ant Design 的 Table 组件进行封装,可以快速构建完整的数据列表页面。
2. 组件属性
| 属性名 | 类型 | 默认值 | 说明 |
|-------|------|-------|------|
| columns | ListTableColumn[] | 必填 | 表格列配置数组 |
| request | (params: any) => Promise<{ data: T[]; success: boolean; total: number }> | 必填(除非提供dataSource) | 数据请求函数 |
| dataSource | T[] | 可选 | 本地数据源,如果提供则不执行request |
| toolBarRender | () => ReactNode[] | 可选 | 自定义工具栏按钮渲染函数 |
| tableTitle | ReactNode | 可选 | 表格标题 |
| pagination | { pageSize?: number; current?: number; total?: number; showSizeChanger?: boolean; showQuickJumper?: boolean; onChange?: (page: number, pageSize: number) => void } \| false | 可选 | 分页配置,传false则不显示分页 |
| ...tableProps | TableProps<T> | 可选 | 其他Ant Design Table组件属性 |
3. ListTableColumn 接口定义
interface ListTableColumn<T = any> extends Omit<ColumnType<T>, 'dataIndex'> {
dataIndex: string; // 数据字段名
hideInSearch?: boolean; // 是否在搜索表单中隐藏
hideInTable?: boolean; // 是否在表格中隐藏
valueEnum?: Pick<FormItem, 'options'> | Record<string, { label: string; value?: string }>; // 枚举值配置
formItemProps?: Omit<FormItem, 'label' | 'name' | 'options'>; // 搜索表单项属性
}4. 使用示例
基础用法(使用远程数据源)
import React from 'react';
import { Button } from 'antd';
import ListTable, { ListTableColumn } from './components/ListTable';
interface User {
id: string;
name: string;
age: number;
gender: 'male' | 'female';
status: 'active' | 'inactive' | 'pending';
createTime: string;
}
const UserListPage: React.FC = () => {
// 列配置
const columns: ListTableColumn<User>[] = [
{
title: '用户ID',
dataIndex: 'id',
key: 'id',
width: 80
},
{
title: '姓名',
dataIndex: 'name',
key: 'name'
},
{
title: '年龄',
dataIndex: 'age',
key: 'age',
width: 80
},
{
title: '性别',
dataIndex: 'gender',
key: 'gender',
width: 80,
valueEnum: {
options: [
{ label: '男', value: 'male' },
{ label: '女', value: 'female' }
]
}
},
{
title: '状态',
dataIndex: 'status',
key: 'status',
width: 100,
valueEnum: {
active: { label: '活跃' },
inactive: { label: '禁用' },
pending: { label: '待审核' }
}
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime'
},
{
title: '操作',
key: 'action',
width: 150,
render: (_, record) => (
<>
<Button type="link" style={{color:'#2BA07F',fontSize:'14px'}} onClick={() => handleEdit(record)}>
编辑
</Button>
<Button type="link" danger onClick={() => handleDelete(record.id)}>
删除
</Button>
</>
)
}
];
// 数据请求函数
const request = async (params: any) => {
// 模拟API请求
console.log('请求参数:', params);
// 实际项目中这里应该调用真实的API
// const response = await api.getUsers(params);
// return response;
// 模拟数据
return {
success: true,
total: 100,
data: Array(10).fill(0).map((_, index) => ({
id: `user_${params.page || 1}_${index + 1}`,
name: `用户${(params.page || 1) * 10 + index}`,
age: 18 + Math.floor(Math.random() * 30),
gender: Math.random() > 0.5 ? 'male' : 'female',
status: ['active', 'inactive', 'pending'][Math.floor(Math.random() * 3)],
createTime: new Date(Date.now() - Math.random() * 10000000000).toISOString()
}))
};
};
// 自定义工具栏
const toolBarRender = () => [
<Button key="add" type="primary" style={{backgroundColor: '#2BA07F', borderColor: '#2BA07F'}}>
添加用户
</Button>
];
// 处理编辑
const handleEdit = (record: User) => {
console.log('编辑用户:', record);
// 实现编辑逻辑
};
// 处理删除
const handleDelete = (id: string) => {
console.log('删除用户:', id);
// 实现删除逻辑
};
return (
<div>
<h2>用户管理列表</h2>
<ListTable
columns={columns}
request={request}
tableTitle="用户列表"
toolBarRender={toolBarRender}
pagination={{
pageSize: 10,
showSizeChanger: true,
showQuickJumper: true
}}
/>
</div>
);
};
export default UserListPage;使用本地数据源
import React from 'react';
import ListTable from './components/ListTable';
const LocalDataPage: React.FC = () => {
// 本地数据源
const localData = [
{ id: '1', name: '张三', age: 25, department: '开发部' },
{ id: '2', name: '李四', age: 30, department: '市场部' },
{ id: '3', name: '王五', age: 35, department: '设计部' }
];
// 列配置
const columns = [
{ title: 'ID', dataIndex: 'id', key: 'id' },
{ title: '姓名', dataIndex: 'name', key: 'name' },
{ title: '年龄', dataIndex: 'age', key: 'age' },
{ title: '部门', dataIndex: 'department', key: 'department' }
];
// 空的请求函数(因为使用本地数据源)
const emptyRequest = async () => ({
success: true,
data: [],
total: 0
});
return (
<ListTable
columns={columns}
request={emptyRequest}
dataSource={localData} // 使用本地数据源
pagination={{
pageSize: 10,
showSizeChanger: false
}}
/>
);
};三、组件组合使用
以下示例展示如何结合 DynamicForm 和 ListTable 组件,构建一个完整的数据管理页面:
import React, { useState } from 'react';
import { Button, Modal, message } from 'antd';
import DynamicForm from './components/DynamicForm';
import ListTable from './components/ListTable';
interface Product {
id: string;
name: string;
price: number;
category: string;
stock: number;
}
const ProductManagementPage: React.FC = () => {
const [isModalVisible, setIsModalVisible] = useState(false);
const [editingProduct, setEditingProduct] = useState<Product | null>(null);
// 产品表单配置
const productFormItems = [
{
label: '产品名称',
name: 'name',
type: 'text',
rules: [{ required: true, message: '请输入产品名称' }]
},
{
label: '产品价格',
name: 'price',
type: 'number',
props: { min: 0, step: 0.01, precision: 2 },
rules: [{ required: true, message: '请输入产品价格' }]
},
{
label: '产品分类',
name: 'category',
type: 'select',
options: [
{ label: '电子产品', value: 'electronics' },
{ label: '服装鞋帽', value: 'clothing' },
{ label: '食品饮料', value: 'food' }
],
rules: [{ required: true, message: '请选择产品分类' }]
},
{
label: '库存数量',
name: 'stock',
type: 'number',
props: { min: 0, step: 1 },
rules: [{ required: true, message: '请输入库存数量' }]
}
];
// 表格列配置
const columns = [
{ title: '产品ID', dataIndex: 'id', key: 'id' },
{ title: '产品名称', dataIndex: 'name', key: 'name' },
{ title: '产品价格', dataIndex: 'price', key: 'price', render: (price) => `¥${price}` },
{ title: '产品分类', dataIndex: 'category', key: 'category' },
{ title: '库存数量', dataIndex: 'stock', key: 'stock' },
{
title: '操作',
key: 'action',
render: (_, record) => (
<>
<Button type="link" style={{color:'#2BA07F',fontSize:'14px'}} onClick={() => handleEdit(record)}>
编辑
</Button>
<Button type="link" danger onClick={() => handleDelete(record.id)}>
删除
</Button>
</>
)
}
];
// 数据请求函数
const request = async (params: any) => {
// 实际项目中这里应该调用真实的API
console.log('请求参数:', params);
// 模拟数据返回
return {
success: true,
total: 50,
data: Array(10).fill(0).map((_, index) => ({
id: `prod_${params.page || 1}_${index + 1}`,
name: `产品${(params.page || 1) * 10 + index}`,
price: 10 + Math.random() * 990,
category: ['electronics', 'clothing', 'food'][Math.floor(Math.random() * 3)],
stock: Math.floor(Math.random() * 1000)
}))
};
};
// 打开添加/编辑模态框
const showModal = (product: Product | null = null) => {
setEditingProduct(product);
setIsModalVisible(true);
};
// 处理编辑
const handleEdit = (product: Product) => {
showModal(product);
};
// 处理删除
const handleDelete = (id: string) => {
console.log('删除产品:', id);
// 实际项目中这里应该调用删除API
message.success('产品删除成功');
};
// 处理表单提交
const handleSubmit = (values: Record<string, unknown>) => {
console.log('提交产品数据:', values);
// 实际项目中这里应该调用保存API
setIsModalVisible(false);
message.success(editingProduct ? '产品更新成功' : '产品添加成功');
setEditingProduct(null);
};
// 自定义工具栏
const toolBarRender = () => [
<Button key="add" type="primary" style={{backgroundColor: '#2BA07F', borderColor: '#2BA07F'}} onClick={() => showModal()}>
添加产品
</Button>
];
return (
<div>
<h2>产品管理系统</h2>
<ListTable
columns={columns}
request={request}
toolBarRender={toolBarRender}
pagination={{
pageSize: 10,
showSizeChanger: true,
showQuickJumper: true
}}
/>
{/* 添加/编辑产品模态框 */}
<Modal
title={editingProduct ? '编辑产品' : '添加产品'}
open={isModalVisible}
onCancel={() => {
setIsModalVisible(false);
setEditingProduct(null);
}}
footer={null}
width={600}
>
<DynamicForm
items={productFormItems}
onSubmit={handleSubmit}
itemsPerRow={1}
/>
</Modal>
</div>
);
};
export default ProductManagementPage;四、主题颜色配置
项目中主题色已配置为 #2BA07F(一种绿色系颜色),在按钮、链接等交互元素中统一使用了这个颜色。如果需要自定义组件的颜色,可以通过 style 属性覆盖默认样式:
<Button
type="link"
style={{color:'#2BA07F',fontSize:'14px'}}
onClick={handleEdit}
>
编辑
</Button>
<Button
type="primary"
style={{backgroundColor: '#2BA07F', borderColor: '#2BA07F'}}
onClick={handleAdd}
>
添加
</Button>五、注意事项
版本兼容性:组件基于 Ant Design v5 开发,使用时请确保项目中 Ant Design 版本与之兼容。
数据格式:使用
ListTable组件时,数据请求函数request需要返回包含data、success和total三个字段的对象。性能优化:对于大量数据,建议使用
request进行分页加载,而不是一次性加载所有数据。表单验证:
DynamicForm组件支持 Ant Design 的表单验证规则,可通过rules属性配置。
