react 实用组件(modal表单)
·
技术介绍
该代码实现了一个高度可配置的表单模态框组件FormModal,基于React和Ant Design构建。核心功能包括动态表单渲染、多列布局支持、多种输入类型适配(文本、日期、下拉选择等),以及与父组件的交互控制。
标题与布局设计
标题通过title属性动态传入,支持自定义。布局设计特点:
- 支持单列或多列布局(通过
columns参数控制) - 使用Ant Design的
Row和Col组件实现响应式网格 - 可通过
gutter参数调整列间距 - 表单布局模式(
formLayout)支持水平或垂直排列
动态表单渲染
- 通过
fields数组配置表单字段 - 支持多种字段类型:文本输入、数字输入、文本域、日期选择器和下拉选择框
- 每个字段可单独配置验证规则、提示信息和禁用状态
类型处理优化
- 使用
switch-case结构处理不同输入类型 - 为每种输入类型提取公共属性(
commonProps) - 支持直接传入自定义组件(通过
component属性)
状态管理
- 使用Ant Design Form的
useFormhook管理表单状态 - 通过
initialValues实现数据回填 - 弹窗关闭时自动重置表单
以下是代码
import React, { useEffect } from 'react';
import { Modal, Form, Input, Row, Col, DatePicker, Select } from 'antd';
const FormModal = ({
visible,
onCancel,
onOk,
title,
initialValues = null,
fields,
columns = 2,
gutter = 16,
formLayout = 'vertical',
okText = "确定",
cancelText = "取消"
}) => {
const [form] = Form.useForm();
// 当initialValues变化时,重置表单
React.useEffect(() => {
if (visible) {
form.setFieldsValue(initialValues || {});
}
}, [visible, initialValues, form]);
const handleOk = async () => {
try {
const values = await form.validateFields();
onOk(values, initialValues);
} catch (error) {
console.error('表单验证失败:', error);
}
};
// 渲染输入组件
const renderInputComponent = (field) => {
const commonProps = {
placeholder: `请输入${field.label}`,
disabled: field.disabled,
...field
};
// 根据字段类型渲染不同的输入组件
switch (field.type) {
case 'textarea':
return <Input.TextArea {...commonProps} rows={4} />;
case 'date':
return <DatePicker {...commonProps} style={{ width: '100%' }} />;
case 'select':
return (
<Select {...commonProps} options={field.options}>
{field.options?.map(option => (
<Select.Option key={option.value} value={option.value}>
{option.label}
</Select.Option>
))}
</Select>
);
case 'number':
return <Input type="number" {...commonProps} />;
default:
return <Input {...commonProps} />;
}
};
// 渲染表单字段
const renderFormFields = () => {
if (columns === 1) {
// 单列布局
return fields.map(field => (
<Form.Item
key={field.name}
name={field.name}
label={field.label}
rules={field.rules}
extra={field.extra}
tooltip={field.tooltip}
>
{field.component || renderInputComponent(field)}
</Form.Item>
));
}
// 多列布局
const rows = [];
for (let i = 0; i < fields.length; i += columns) {
const rowFields = fields.slice(i, i + columns);
const rowItems = rowFields.map(field => (
<Col span={24 / columns} key={field.name}>
<Form.Item
name={field.name}
label={field.label}
rules={field.rules}
extra={field.extra}
tooltip={field.tooltip}
>
{field.component || renderInputComponent(field)}
</Form.Item>
</Col>
));
rows.push(
<Row gutter={gutter} key={`row-${i}`}>
{rowItems}
</Row>
);
}
return rows;
};
return (
<Modal
afterClose={() => {
// 弹窗完全关闭后再次重置表单
form.resetFields();
}}
title={title}
visible={visible}
onOk={handleOk}
onCancel={() => {
form.resetFields();
onCancel();
}}
okText={okText}
cancelText={cancelText}
destroyOnClose
width={800} // 增加宽度以适应更多字段
>
<Form
form={form}
layout={formLayout}
initialValues={initialValues || {}}
>
{renderFormFields()}
</Form>
</Modal>
);
};
export default FormModal;
<FormModal
title={'编辑'}
visible={modifyOrderModal}
onOk={modifyOrderModalOk}
onCancel={modifyOrderModalCancel}
fields={modifyOrderFields}
initialValues={selectedRowOrder}
>
</FormModal>
const modifyOrderFields = [
{
name: 'orderNo',
label: '工单名称',
rules: [{ required: true, message: '请输入工单名称' }]
},
{
name: 'orderNo',
label: '标准工时',
rules: [{ required: true, message: '请输入标准工时' }],
type: 'number'
},
{
name: 'orderCount',
label: '工单数',
rules: [{ required: true, message: '请输入工单数' }],
type: 'number'
},
]
扩展性有待提高
更多推荐


所有评论(0)