我们希望快速构建form表单,但是还得写检验,绑定数据等等,往往比较麻烦。
我们希望代码这样就可以实现一个表单的基本需求
👇
[
{type: 'input', title: '您的姓名', width: '331px' },
{type: 'input', title: '您的手机号码', width: '331px', pattern: /^1{1}\d{10}$/, message: '请输入正确的手机号'},
{type: 'radios', title: '教育背景', data: ['专科以下', '专科'], },
...
{type: 'input', textArea: true, title: '希望老师协助解答的问题', rows: 4, required: false},
]
根据数据结构生成简单的表单,再写一个回调函数,请求后台即可。
我基于antd写了一个简单的代码封装,使用的例子如下
使用例子
const [formloading, setformloading] = useState(false)
const [formJSON] = useState<typeFormJSON>([
{type: 'input', title: '您的姓名', width: '331px' },
{type: 'input', title: '您的手机号码', width: '331px', pattern: /^1{1}\d{10}$/, message: '请输入正确的手机号'},
{type: 'radios', title: '教育背景', data: ['专科以下', '专科'], },
...
{type: 'input', textArea: true, title: '希望老师协助解答的问题', rows: 4, required: false},
])
const onFinish = async (value: any) => {
setformloading(true)
console.log(value)
// await Axios.post('[web]/xx', value)
setformloading(false)
// TODO 成功处理
}
return <div>
<div>
<Form onFinish={onFinish}>
<JSONToForm json={formJSON} />
<Form.Item>
<Button type="primary" htmlType="submit" loading={formloading} className={styles.button}>提交信息</Button>
</Form.Item>
</Form>
</div>
</div>
如何实现
可以看到,这里有一个JSONToForm组件,这个组件我们实现下,就可以了。我的实现组件代码
import React from 'react'
import {Form, Radio, Button, Input} from 'antd'
import TextArea from 'antd/lib/input/TextArea'
interface typeFormJSONInput {
type: 'input';
// 展示标题
title: string;
// 是否是必填/必选,默认必填/必选
required?: boolean;
// 设置宽度,默认100%
width?: string;
// 是否是文本域, 默认否
textArea?: boolean;
// 文本域的rows
rows?: number;
// 正则
pattern?: RegExp;
// 自定义消息 默认: 请输入+title
message?: string;
}
interface typeFormJSONRadios {
type: 'radios';
// 展示标题
title: string;
// 数组数据
data: string[];
// 是否是必填/必选,默认必填/必选
required?: boolean;
}
export type typeFormJSON = (typeFormJSONInput | (typeFormJSONRadios))[]
export function JSONToForm({json}: {json: typeFormJSON}){
return <div>
{json.map(row =>
row.type == 'radios' ? <Form.Item label={row.title} name={row.title} rules={[{
required: row.required !== void 0 ? row.required : true,
message: `请选择${row.title}`
}]}>
<Radio.Group onChange={(e) => console.log(e)} value={row.title}>
{row.data.map(dateItem => <Radio value={dateItem}>{dateItem}</Radio>)}
</Radio.Group>
</Form.Item> :
row.type == 'input' ? <Form.Item label={row.title} name={row.title} rules={[{
required: row.required !== void 0 ? row.required : true,
pattern: row.pattern,
message: row.message || `请输入${row.title}`
}]}>
{row.textArea
? <TextArea rows={row.rows} value={row.title} placeholder={`请输入${row.title}`} />
: <Input style={{width: row.width}} value={row.title} placeholder={`请输入${row.title}`} />}
</Form.Item> :
<></>
)}
</div>
}
这里用到了antd做form的主要渲染,然后我们要做的就是改成json渲染的形式。
效果
点击获取到的值
然后把这个json化再传给后台,后台管理系统展示的时候,再Object.kes渲染即可。
--完--