我在封装详情页功能的时候,其实最早的雄心壮志是做低代码平台。看了几篇文章,再看看自己的小键盘以及手里的项目排期,就放弃了。我和我的梦想终究是隔着时间、人力、能力等多重重险阻。
但是,我转念一想,如果把前端的功能简化,不就有时间做低代码平台的开发了吗?对于自己的机智,反手就是一个赞。
于是开始计划,最大化的模块化和组件化前端功能,这样一来,每次新需求开发就会非常的便捷。而后台系统,最复杂也最啰嗦的就是表单功能,所以我准备将表单做成组件化的。
表单功能不用再重复的码一些个输入框、下拉项、日期控件等代码,是不是节省了很多时间,节省出来的时间又可以去研究低代码开发,是不是离财富自由更近了一步。(✧◡✧)
基于React框架开发,使用的antd UI组件库。
antd提供的Form表单控件,已经集成了数据录入、校验以及对应样式等。但是我们实际开发的时候,后台系统的添加、编辑、其他数据录入等表单弹窗,内容项大多是Input、Radio、CheckBox等,每次开发都重复码一些代码。所以我根据日常开发经验,将常规的表单项做了进一步的封装处理。
封装处理之后,只需将表单项类型、key值等关键变量放到一个数组对象中,通过props传递到表单组件中即可。
当表单填写完成之后,填写的数据会通过callback函数回传到表单弹窗中。
参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
data | 表单默认数据 | object | {} |
list | 表单项展示数组 | any[] | [] |
layout | 表单布局 | object | - |
callback | 提交操作的回调函数 | (value,list) => void | |
getFormRef | 获取formRef方法 | (formRef) => void |
目前支持的表单项类型如下,未来如果有新的开发思路,会继续增加
类型 | key |
|---|---|
输入框 | input |
数值型输入框 | inputNumber |
日期 | date |
下拉选择器 | select |
多选框 | checkbox |
单选框 | radio |
文本域 | textArea |
纯文本展示 | text |
细节处理只放关键代码,完整代码已经放到github上了,github地址在文末。下面主要将设计思路和实现方式
list数组,根据每个元素的fieldtype区分不同的展示内容。
{
list.map((formItem, formIndex) => {
return (
<Fragment key={formIndex}>
{formItem.fieldtype === 'input' && inputContent(formItem)}
{formItem.fieldtype === 'inputNumber' && inputNumberContent(formItem)}
......
</Fragment>
);
});
}/**
* 输入框类型
* @param {object} item 表单项
*/
const inputContent = item => {
return (
<>
{item.children ? (
item.children
) : (
<Form.Item label={item.label} name={item.key} rules={item.rules} disabled={item.disabled}>
<Input placeholder={`请输入${item.label}`} />
</Form.Item>
)}
</>
);
};<Form.Item label={item.label} className={classnames({ required: item.required })}>
<Form.Item noStyle name={item.key} rules={item.rules} disabled={item.disabled}>
<InputNumber style={{ width: '50%' }} step={item.step} min={item.min} max={item.max} precision={item.precision} />
</Form.Item>
{item.unit && <span style={{ marginLeft: '10px' }}>{item.unit}</span>}
</Form.Item>{/* 下拉项中有需要文本输入的情况 */}
{item.textArea.code && item.option.value === item.textArea.code ? textAreaContent(item.textArea) : null}let areaLayout = {};
if (type === 'other') {
areaLayout = { wrapperCol: { offset: layout.labelCol, span: layout.wrapperCol } };
label = null;
}纯展示类型,展示具体内容即可。
import BaseFormUI from '@/components/BaseFormUI';
......
const config = {
data: {
...data,
initFieldsValueFlag: true,
},
list: list,
getFormRef: getFormRef,
callback: callback,
};
......
<BaseFormUI {...config} />
如果后端接口没有特殊要求,value对象中的数据基本就满足了,如果需要其他值可以从list中获取。

github地址:react-antd-manage
功能完成之后,发现没有自己最开始设想的那么复杂。当然了,也跟功能的兼容程度有关系,不适用特别复杂的表单,比如表格类的表单。
未来希望伴随着学习和进步,进一步完善表单组件。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。