封装一个antd的Form表单
效果:
只需传入配置文件
定义配置类型
整体:
import React, { memo, useEffect, useRef } from "react";
import { Form, Input, Button, Checkbox, Select, FormInstance } from "antd";
import { Props } from "./type";
import "./HFrom.style.scss";
import { Upload } from "@/components";
function HFrom<T = unknown>({
FormItems,
FormProps,
footer,
onValChange,
onFinish,
search,
}: Props<T>) {
const [form] = Form.useForm();
useEffect(() => {
if (search && form) {
form.setFieldsValue(search);
}
}, [search]);
const normFile = (e: any) => {
//如果是typescript, 那么参数写成 e: any
console.log("Upload event:", e);
if (Array.isArray(e)) {
return e;
}
return e && e.fileList;
};
return (
<div className={"hfrom"}>
<Form
onFinish={onFinish}
onValuesChange={onValChange}
{...FormProps}
form={form}
>
{FormItems.length &&
FormItems.map((item) => {
const { FormType, ContentProps, ...otherProps } = item;
switch (FormType) {
case "input":
return (
<Form.Item {...otherProps}>
<Input {...ContentProps} />
</Form.Item>
);
case "password":
return (
<Form.Item {...otherProps}>
<Input type="password" {...ContentProps} />
</Form.Item>
);
case "select":
return (
<Form.Item {...otherProps}>
<Select {...ContentProps} />
</Form.Item>
);
case "submit":
return !footer ? (
<Form.Item {...otherProps}>
<Button {...ContentProps}> 提交</Button>
</Form.Item>
) : null;
case "upload":
return (
<Form.Item
valuePropName="fileList"
getValueFromEvent={normFile}
{...otherProps}
>
<Upload {...ContentProps}></Upload>
</Form.Item>
);
default:
return null;
}
})}
{footer ? <Form.Item>{footer}</Form.Item> : null}
</Form>
</div>
);
}
export { HFrom };
利用es6的解构赋值,将对应的props传给对应的dom。
数据交互
对外传出暴露
onValChange和一个onFinisth函数,外部可以通过该函数修改state状态,然后将该state传给组件
通过antd提供的api将form的值修改为search,实现数据双向绑定。因为searc状态是在外部确定的,故不会影响数据单一流的原则。
自定义formitem的实现
因为upload组件是封装antd的,
关键在于必须实现两个参数,value和onChange
在内部只要实现其逻辑就行。
外部就可以正常使用
效果如上面一样。
这只是一个简易的封装,可以封装更多的api实现更加复杂的逻辑,不过如果太复杂建议还是不要使用该组件,自己写antd的反而更好点
未完待续。。。。