Procomponents是基于Ant Design封装的开箱即用的页面级组件。平时在做中台项目时经常会遇到编辑、查看复杂表单的需求,Schema Form预设了多种控件,通过JSON Schema可以快速生成表单,实现字段依赖、编辑表单、查看表单。但是在实际业务中通常会用到自己封装的业务组件,这里分享下两种实现自定义组件的方式
一、使用 renderFormItem 返回自定义组件
封装自定义上传组件,方法同antd自定义控件,form表单会提供value onChange给自定义组件使组件受控
// CustomUpload
const CustomUpload = (props) => {
const [fileList, setFileList] = useState([]);
useEffect(() => {
setFileList(props.value || []);
}, [props.value]);
return (
<Upload
fileList={fileList}
customRequest={(file) => {
const result = [
{
status: "done",
url: "https://xxxxx.png",
uid: "1",
name: file.file?.name?.replace(".png", "") || "文件a",
},
];
setFileList(result);
props.onChange?.(result);
}}
accept="image/*"
>
<Button>上传</Button>
</Upload>
);
};
export default CustomUpload;
使用自定义上传组件
const FormPro = () => {
const [, setData] = useState(null);
const [readOnly, setReadOnly] = useState(false);
const columns = [
{
title: "自定义renderFormItem",
dataIndex: "file",
render(dom) {
return <div>{dom[0].name}</div>;
},
renderFormItem() {
return <CustomUpload></CustomUpload>;
},
colProps: {
span: 8,
},
},
];
const finish = (values: FormData) => {
setData(values);
setReadOnly(!readOnly);
};
return (
<div>
<BetaSchemaForm
grid
columns={columns}
layout="horizontal"
wrapperCol={{ span: 18 }}
onFinish={finish}
readonly={readOnly}
submitter={{
searchConfig: {
submitText: readOnly ? "编辑" : "查看",
},
}}
></BetaSchemaForm>
</div>
);
};
二、使用自定义valueType实现自定义组件
对于全局组件来说在每个用到的表单中都要写一遍renderFormItem和render方法太麻烦了,Procomponents提供了自定义valueType的方式。(自定义组件同上)
function App() {
const valueTypeMap = {
upload: {
renderFormItem: (_, props) => {
return <CustomUpload {...props.fieldProps}></CustomUpload>;
},
render(text) {
return text[0].name;
},
},
};
return (
<div>
<ProProvider.Provider
value={{
valueTypeMap,
}}
>
<FormPro></FormPro>
</ProProvider.Provider>
</div>
);
}
const FormPro = () => {
const [, setData] = useState<FormData | null>(null);
const [readOnly, setReadOnly] = useState(false);
const [form] = Form.useForm();
const columns: ProFormColumnsType<FormData, "upload">[] = [
{
title: "全局组件",
dataIndex: "file1",
valueType: "upload",
colProps: {
span: 8,
},
}
];
const finish = (values: FormData) => {
setData(values);
setReadOnly(!readOnly);
};
return (
<div>
<BetaSchemaForm<FormData, "upload">
form={form}
grid
columns={columns}
layout="horizontal"
wrapperCol={{ span: 18 }}
onFinish={finish}
readonly={readOnly}
submitter={{
searchConfig: {
submitText: readOnly ? "编辑" : "查看",
},
}}
></BetaSchemaForm>
</div>
);
};