基于react,antd v4 搭配antd-form-render可以轻松实现各类表单
尝试地址: github.com/leonwgc/ant…
- 一行一列布局
import React from 'react';
import styled from 'styled-components';
import { Form, Button, Space, Input, message } from 'antd';
import FormRender from 'antd-form-render';
const StyledOneRow = styled.div`
width: 400px;
`;
const OneCol = () => {
const [form] = Form.useForm();
const oneRowLayout = [
{
type: Input,
label: '手机号',
placeholder: '请输入',
name: 'tel',
elProps: {
maxLength: 11,
},
itemProps: {
rules: [
{ required: true, message: '请输入' },
{ pattern: /^1\d{10}$/, message: '手机号必须为11位数字' },
],
},
},
{
type: Input.Password,
label: '密码',
placeholder: '请输入',
name: 'pwd',
itemProps: {
rules: [{ required: true, message: '请输入' }],
},
},
{
type: Input.Password,
label: '确认密码',
placeholder: '请输入',
name: 'confirmPwd',
itemProps: {
rules: [
{ required: true, message: '请输入' },
({ getFieldValue }) => ({
validator(_, value) {
if (!value || getFieldValue('pwd') === value) {
return Promise.resolve();
}
return Promise.reject(new Error('两次密码不一致'));
},
}),
],
},
},
{
type: Input.TextArea,
name: 'desc',
label: '简介',
elProps: {
placeholder: '个人简介',
rows: 4,
},
},
{
// 自定义render
render() {
return (
<Form.Item wrapperCol={{ offset: 6 }}>
<Space>
<Button htmlType="submit" type="primary">
确定
</Button>
<Button htmlType="reset">重置</Button>
</Space>
</Form.Item>
);
},
},
];
return (
<StyledOneRow>
<Form
form={form}
labelCol={{ span: 6 }}
onFinish={(v) => {
message.success(JSON.stringify(v));
}}
>
<FormRender layoutData={oneRowLayout}></FormRender>
</Form>
</StyledOneRow>
);
};
export default OneCol;
复制代码
- 一行多列布局
import React, { useState } from 'react';
import styled from 'styled-components';
import { Input, Radio, Form } from 'antd';
import FormRender from 'antd-form-render';
const StyledOneRow = styled.div`
width: 800px;
`;
const MultipleCols = () => {
const layout = [];
const [cols, setCols] = useState(4);
for (let i = 0; i < 11; i++) {
layout.push({
type: Input,
label: `输入框${i + 1}`,
placeholder: '请输入',
name: `name${i}`,
});
}
return (
<StyledOneRow>
<Form layout="vertical">
<div style={{ margin: '16px 0' }}>
<Radio.Group
onChange={(e) => setCols(Number(e.target.value))}
optionType="button"
value={cols}
>
<Radio value={1}>1行1列</Radio>
<Radio value={2}>1行2列</Radio>
<Radio value={3}>1行3列</Radio>
<Radio value={4}>1行4列</Radio>
</Radio.Group>
</div>
<FormRender layoutData={layout} cols={cols}></FormRender>
</Form>
<FormRender layoutData={layout}></FormRender>
</StyledOneRow>
);
};
export default MultipleCols;
复制代码
- 等间距排列 (常用于列表页面的搜索等)
import React, { useState } from 'react';
import styled from 'styled-components';
import { Input, Radio, Form } from 'antd';
import { FormSpaceRender } from 'antd-form-render';
const StyledOneRow = styled.div`
width: 1000px;
`;
const SpaceLayout = () => {
const layout = [];
const [space, setSpace] = useState(8);
for (let i = 0; i < 3; i++) {
layout.push({
type: Input,
label: `输入框${i + 1}`,
placeholder: '请输入',
name: `name${i}`,
});
}
return (
<StyledOneRow>
<Form layout="horizontal">
<div style={{ margin: '16px 0' }}>
<Radio.Group
onChange={(e) => setSpace(Number(e.target.value))}
optionType="button"
value={space}
>
<Radio value={8}>8px</Radio>
<Radio value={16}>16px</Radio>
<Radio value={24}>24px</Radio>
<Radio value={32}>32px</Radio>
</Radio.Group>
</div>
<FormSpaceRender layoutData={layout} size={space}></FormSpaceRender>
</Form>
</StyledOneRow>
);
};
export default SpaceLayout;
复制代码
4.表单联动
import React, { useState } from 'react';
import styled from 'styled-components';
import { Form, Button, Radio, message } from 'antd';
import FormRender from 'antd-form-render';
const StyledOneRow = styled.div`
width: 600px;
`;
const StyledP = styled.p`
padding: 10px;
`;
const OneColWithDynamicControl = () => {
const [form] = Form.useForm();
const [form1] = Form.useForm();
// 用于同步表单状态
const [data, setData] = useState({});
const layout = [
{
type: Radio.Group,
label: '性别',
name: 'gender',
elProps: {
options: [
{ label: '男', value: '男生' },
{ label: '女', value: '女生' },
],
},
},
{
type: 'div',
label: '你是',
elProps: {
children: data.gender || '未选择',
},
},
{
type: Button,
elProps: {
htmlType: 'submit',
type: 'primary',
children: '确定',
},
itemProps: {
wrapperCol: { offset: 6 },
},
},
];
// 基于antd , dependency 实现表单联动
const layout1 = [
{
type: Radio.Group,
label: '性别',
name: 'gender',
elProps: {
options: [
{ label: '男', value: '男生' },
{ label: '女', value: '女生' },
],
},
},
{
render() {
return (
<Form.Item label="你是" dependencies={['gender']}>
{() => {
const gender = form1.getFieldValue('gender');
return gender || '未选择';
}}
</Form.Item>
);
},
},
{
type: Button,
elProps: {
htmlType: 'submit',
type: 'primary',
children: '确定',
},
itemProps: {
wrapperCol: { offset: 6 },
},
},
];
return (
<StyledOneRow>
<StyledP>1.定义onValuesChange 同步状态到state , 触发重新渲染实现表单联动</StyledP>
<Form
form={form}
onValuesChange={(v) => {
setData((p) => ({ ...p, ...v }));
}}
labelCol={{ span: 6 }}
onFinish={(v) => {
message.success(JSON.stringify(v));
}}
>
<FormRender layoutData={layout}></FormRender>
</Form>
<StyledP>2.利用Form.Item dependencies 和自定义render 实现表单联动</StyledP>
<Form
form={form1}
labelCol={{ span: 6 }}
onFinish={(v) => {
message.success(JSON.stringify(v));
}}
>
<FormRender layoutData={layout1}></FormRender>
</Form>
</StyledOneRow>
);
};
export default OneColWithDynamicControl;
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END