我们希望快速构建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渲染即可。
--完--