"Function realization" I encapsulated a form component, I feel one step closer to wealth freedom

When I was encapsulating the details page function, my earliest ambition was to be a low-code platform. After reading a few articles, and then looking at my keyboard and the project schedule in my hand, I gave up. After all, my dream and I are separated by multiple obstacles such as time, manpower, and ability.

However, I thought about it, if the front-end functions are simplified, wouldn't there be time for low-code platform development? The backhand is a compliment for his wit.

So start planning to maximize the modularity and componentization of front-end functions, so that every new requirement development will be very convenient. In the background system, the most complicated and verbose thing is the form function, so I plan to make the form componentized.

The form function does not need to repeatedly code some input boxes, drop-down items, date controls and other codes, does it save a lot of time, and the time saved can be used to study low-code development, is it a step closer to wealth freedom? (✧◡✧)

Developed based on the React framework, using the antd UI component library.

overall design

Features

The Form control provided by antd has integrated data entry, validation and corresponding styles. However, when we actually develop, the form pop-ups such as adding, editing, and other data entry in the background system, most of the content items are Input, Radio, CheckBox, etc., and some code is repeated every time we develop. So I further encapsulated regular form items based on my daily development experience.

After the encapsulation processing, you only need to put key variables such as the form item type and key value into an array object and pass it to the form component through props.

When the form is filled out, the filled-in data will be returned to the form pop-up window through the callback function.

Parameter introduction

parameter illustrate type Defaults
data form default data object {}
list form item display array any[] []
layout form layout object -
callback The callback function for the submit operation (value,list) => void
getFormRef Get formRef method (formRef) => void

form item type

The currently supported form item types are as follows, if there are new development ideas in the future, it will continue to increase

type key
Input box input
Numeric input box inputNumber
date date
drop down selector select
Checkbox checkbox
Single box radio
text field textArea
Plain text display text

Details

细节处理只放关键代码,完整代码已经放到github上了,github地址在文末。下面主要将设计思路和实现方式

类型区分

list数组,根据每个元素的fieldtype区分不同的展示内容。

{
  list.map((formItem, formIndex) => {
    return (
      <Fragment key={formIndex}>
        {formItem.fieldtype === 'input' && inputContent(formItem)}
        {formItem.fieldtype === 'inputNumber' && inputNumberContent(formItem)}
        ......
      </Fragment>
    );
  });
}
复制代码

input

  • 输入框使用的antd提供的Input组件。
  • 如果输入框类型的内容项,展示内容不单单是输入框,可能还包含其他的比如提示文案,可以使用children进行内容替换。
/**
 * 输入框类型
 * @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>
      )}
    </>
  );
};
复制代码

inputNumber

  • 输入框使用的antd提供的InputNumber组件。
  • 数字类型的输入框的特别之处在于输入的数值可以设置最小值和最大值、小数点、每次可以改变的步数。这些都可以通过设置对应的属性进行控制。
  • 数字类型的输入框支持展示单位,通过unit变量控制单位的展示。
<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>
复制代码

date

  • 日期类型使用的antd提供的DatePicker组件。
  • 日期类型支持不同的时间展示方式,通过format变量实现。
  • 日期类型可以设置可选时间范围,可选范围包括起日和止日,也可单独设置起日或止日。
  • 写文档的时候突然意识到,实际日期类型也可以支持日期精确到年或是月或是日,目前组件没有实现这个功能,后续实现之后再更新文档。(灵感就是这么一瞬间就来了)

select

  • 下拉选择器类型使用的antd提供的Select组件。
  • 下拉选择器操作一般获取的是value,如果需要拿到选中的节点文本 label,通过onChange时间设置option变量的值为选择的下拉项的值。
  • 有一种特殊情况,当下拉项选择其他时,需要输入其他选项的具体值,所以增加了可输入其他的文本域功能。
{/* 下拉项中有需要文本输入的情况 */}
{item.textArea.code && item.option.value === item.textArea.code ? textAreaContent(item.textArea) : null}
复制代码

checkbox

  • 多选框类型使用的antd提供的Checkbox组件。

radio

  • 单选框类型使用的antd提供的Radio组件。
  • 有一种特殊情况,当单选项选择否或拒绝时,需要输入原因或者说明,所以增加了可输入其他的文本域功能。

textArea

  • 文本域类型使用的antd提供的Input.TextArea组件。
  • 当文本域类型表单项和其他表单项组合展示时,展示的布局值需要和组合的表单项一致,所以根据type类型做了特殊处理。
let areaLayout = {};
if (type === 'other') {
  areaLayout = { wrapperCol: { offset: layout.labelCol, span: layout.wrapperCol } };
  label = null;
}
复制代码

text

纯展示类型,展示具体内容即可。

如何使用

引入组件

  • 一般公共组件会放在components。完整的代码已经放github上了,github地址在文末。,这里不在重复,主要将一下实现思路。
  • data,基础数据对象,里面放一些表单初始化的数据,比如编辑的时候,表单需要回显之前填过的数据,所以我把这部分数据放到了data里面。
  • list,这个是重点,它是一个数组对象,放完整的表单数据,所有需要展示的表单项都要放到list数组中,
  • callback,是一个回调函数,提交表单时,需要请求后端提供的接口进行数据上报。callback函数中的参数value包含所有表单项的操作值。
  • getFormRef,是一个操作函数,有一些弹窗的操作按钮需要特殊处理,不是通过From组件上的onFinish方法进行的操作,所以需要将formRef返回到弹窗中,获取实际的操作。
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

功能完成之后,发现没有自己最开始设想的那么复杂。当然了,也跟功能的兼容程度有关系,不适用特别复杂的表单,比如表格类的表单。

未来希望伴随着学习和进步,进一步完善表单组件。

我正在参与掘金技术社区创作者签约计划招募活动,点击链接报名投稿

Guess you like

Origin juejin.im/post/7119903885061259301