二次封装antd表单FormPro

巨型表单慎用,封装此组件的目的是为了简化基础表单开发,或方便个人demo编写

FormPro组件

index.tsx

import React, { useCallback } from 'react';
import { Form, FormProps, FormInstance } from 'antd';
import { IType, ItemType, renderItem } from './const';

interface IProps {
  form: FormInstance;
  items: ItemType[];
  formProps?: FormProps;
}

export default function FormPro(props: IProps) {
  const { items, formProps = {} } = props;
  const [form] = Form.useForm();

  // Form.Item 校验配置
  const getRules = useCallback((rules, required: boolean) => {
    if (Array.isArray(rules) && rules?.length) {
      return rules;
    }

    if (required) {
      return [{ required: true, message: '请输入' }];
    }

    return [];
  }, []);

  return (
    <Form labelCol={{ span: 3 }} {...formProps} form={form}>
      {items?.map((item) => {
        if (!!item?.isHidden || !Object.keys(item)?.length) {
          return null;
        }

        // 自定义渲染表单
        if (item?.render) {
          return item.render();
        }

        const rules = getRules(item?.formItemProps?.rules, !!item?.required);
        const inputProps = {
          options: item?.options ?? [],
          ...(item?.inputProps ?? {}),
        };
        const children = renderItem(item?.type as IType, inputProps);

        return (
          <Form.Item key={item.name} label={item.label} name={item.name} rules={rules} {...(item?.formItemProps ?? {})}>
            {children}
          </Form.Item>
        );
      })}
    </Form>
  );
}

const.tsx

import {
  DatePicker,
  DatePickerProps,
  Input,
  InputNumber,
  InputNumberProps,
  InputProps,
  Radio,
  RadioGroupProps,
  Select,
  SelectProps,
  TimePickerProps,
  Checkbox,
  FormItemProps,
} from 'antd';
import { CheckboxGroupProps } from 'antd/es/checkbox';
import { RangePickerProps } from 'antd/es/date-picker';
import { TextAreaProps } from 'antd/es/input';

interface IOptions {
  label: string;
  value: any;
}

export type IType =
  | 'Input'
  | 'TextArea'
  | 'InputNumber'
  | 'Select'
  | 'DatePicker'
  | 'TimePicker'
  | 'RangePicker'
  | 'RadioGroup'
  | 'CheckboxGroup';
type PropsMap = {
  Input: InputProps;
  TextArea: TextAreaProps;
  InputNumber: InputNumberProps;
  Select: SelectProps;
  DatePicker: DatePickerProps;
  TimePicker: TimePickerProps;
  RangePicker: RangePickerProps;
  RadioGroup: RadioGroupProps;
  CheckboxGroup: CheckboxGroupProps;
};

export interface ItemType<T extends IType = IType> {
  label?: string;
  name?: string;
  type?: T;
  /** 优先级更高 */
  formItemProps?: FormItemProps;
  required?: boolean;
  /** 优先级更高 */
  inputProps?: PropsMap[T];
  options?: IOptions[];
  /** 配置自定义组件时,label和name只有字段描述作用 */
  render?: () => React.ReactNode;
  /** 展示false/隐藏true */
  isHidden?: boolean;
}

export const renderItem = (type: IType, props) => {
  switch (type) {
    case 'Input':
      return <Input placeholder="请输入" {...props} />;
    case 'TextArea':
      return <Input.TextArea placeholder="请输入" {...props} />;
    case 'InputNumber':
      return <InputNumber placeholder="请输入" controls={false} {...props} />;
    case 'Select':
      return <Select placeholder="请选择" {...props} />;
    case 'DatePicker':
      return <DatePicker {...props} />;
    case 'TimePicker':
      return <DatePicker.TimePicker {...props} />;
    case 'RangePicker':
      return <DatePicker.RangePicker {...props} />;
    case 'RadioGroup':
      return <Radio.Group {...props} />;
    case 'CheckboxGroup':
      return <Checkbox.Group {...props} />;

    default:
      return <Input placeholder="请输入" {...props} />;
  }
};

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值