antd form+upload把上传后的文件删除后,表单校验失效了
const [file, setFile] = useState();
const [form] = Form.useForm();
const props: UploadProps = {
name: 'file',
showUploadList: true, //是否展示上传后的文件列表
accept: '.bin,.tar,.gz,.zip',
maxCount: 1, //最大上传文件数
customRequest: async (options) => {
//这里是我根据项目需求自定义的上传成功操作,小伙伴们可不管,但注意这里要设置file的内容,否则后面不管成功失败都会报错
const { file, onSuccess, onProgress } = options;
onProgress(file);
const md5 = await getMD5(file);
if (md5 === 'error') message.error('md5解析失败');
getBase64(file, (url) => {
let finalFile = {
file,
md5,
size: file.size,
content: url,
};
setFile(finalFile);//注意这里要设置file
onSuccess(finalFile, undefined);
});
},
onRemove: (file) => {
setFile(null);
},
};
<Form
form={form}
layout="horizontal"
name="nest-messages"
onFinish={onFinish}
>
<Form.Item
name="file"
label=“选择文件"
rules={[
{
required: true,
message: '必选',
},
]}
>
<Upload {...props}>
<Button icon={<PlusOutlined />}>点击选择</Button>
<span className="hint">
仅支持 bin, tar, gz, zip 类型的文件,文件大小不能超过 1024MB
</span>
</Upload>
</Form.Item>
</Form>
在提交之前再判断一下
我的表单提交是写在弹出框中的,
onRemove中将file置为空,这里提交前先判断一下file如果不在了就将form中的file表单域值也置为空
这里的setFieldsValue我试过直接写在onRemove中,本想在remove时就直接将表单项置空,但是结果提交时发现表单中file还是有值,所以需要在提交之前再判断一波
<Modal
title="添加固件"
visible={visible}
onCancel={() => cancelModal('')}
onOk={() => {
//————关键———
//onRemove中将file置为空,这里提交前先判断一下file如果不在了就将form中的file表单域值也置为空
//这里的setFieldsValue我试过直接写在onRemove中,本想在remove时就直接将表单项置空,但是结果提交时发现表单中file还是有值,所以需要在提交之前再判断一波
if (!file) {
form.setFieldsValue({
file: '',
});
}
//————关键-------
form.validateFields()
.then(async (values) => {
// 检验成功时;
form.resetFields();
form.setFieldsValue(values); // 例:{tagName:'888'}
await okModal(values, file);
})
.catch((info) => {
// 检验失败时;
console.log('校验失败:', info);
});
}}
>
<Form ………………/>
</Modal>
在弹出框中写表单的部分不是此次重点,所以省略,感兴趣的小伙伴可以去看我之前的文章
antd+ Umi使用中出现的问题集合(一)之 antd中Modal结合form的复合使用
最后来看一下最终效果吧
顺便附上全部代码
import {
Form,
Input,
Modal,
Upload,
Button,
message,
Descriptions,
} from 'antd';
import { useEffect, useState } from 'react';
import { PlusOutlined } from '@ant-design/icons';
import type { UploadProps } from 'antd';
import { RcFile, UploadChangeParam, UploadFile } from 'antd/lib/upload';
import config from '@/config/dev';
import { uploadFile } from '@/api/file';
import { filterUnit, getMD5, transferSize } from '@/utils';
const API_URL = config.apiBase;
const token = localStorage.getItem('token');
export const AddUpgradeForm = (params: any) => {
const { visible, cancelModal, okModal } = params;
const [file, setFile] = useState<any>();
const [form] = Form.useForm();
useEffect(() => {
form.resetFields();
form.setFieldsValue({
name: '',
description: '',
product: '',
version: '',
});
}, []);
const onFinish = async (values: any) => {};
const props: UploadProps = {
name: 'file',
showUploadList: true,
accept: '.bin,.tar,.gz,.zip',
maxCount: 1,
// beforeUpload: async (file) => {
// const md5 = await getMD5(file)
// if (md5 === 'error') message.error('md5解析失败');
// getBase64(file, url => {
// let finalFile = {
// file,
// md5,
// size: transferSize(file.size),
// content: url
// }
// setFile(finalFile);
// })
// },
customRequest: async (options) => {
const { file, onSuccess, onProgress } = options;
onProgress(file);
const md5 = await getMD5(file);
if (md5 === 'error') message.error('md5解析失败');
getBase64(file, (url) => {
let finalFile = {
file,
md5,
size: file.size,
content: url,
};
setFile(finalFile);
onSuccess(finalFile, undefined);
});
},
onRemove: (file) => {
setFile(null);
},
};
const getBase64 = (img: any, callback: (url: string) => void) => {
const reader = new FileReader();
reader.addEventListener('load', () => callback(reader.result as string));
reader.readAsDataURL(img);
};
return (
<Modal
title="添加固件"
visible={visible}
onCancel={() => cancelModal('')}
onOk={() => {
if (!file) {
form.setFieldsValue({
file: '',
});
}
form
.validateFields()
.then(async (values) => {
// 检验成功时;
form.resetFields();
form.setFieldsValue(values); // 例:{tagName:'888'}
await okModal(values, file);
})
.catch((info) => {
// 检验失败时;
console.log('校验失败:', info);
});
}}
>
<Form
form={form}
layout="horizontal"
name="nest-messages"
labelCol={{ span: 4 }}
wrapperCol={{ span: 20 }}
onFinish={onFinish}
>
<Form.Item
name="name"
label="固件名称"
rules={[
{
required: true,
message: '必填',
},
]}
>
<Input />
</Form.Item>
<Form.Item
name="version"
label="固件版本"
rules={[
{
required: true,
message: '必填',
},
{
pattern: /^[a-zA-Z0-9_\.-]{0,31}$/,
message: '请填写正确格式',
},
]}
>
<Input placeholder="仅支持英文字母、数字、点、中划线和下划线,长度限制1~32" />
</Form.Item>
<Form.Item
name="product"
label="产品名称"
rules={[
{
required: true,
message: '必填',
},
]}
>
<Input />
</Form.Item>
<Form.Item name="description" label="固件描述" rules={[]}>
<Input.TextArea rows={2} />
</Form.Item>
<Form.Item
name="file"
label="选择固件"
rules={[
{
required: true,
message: '固件必选',
},
]}
>
<Upload {...props}>
<Button icon={<PlusOutlined />}>点击选择固件</Button>
<span className="hint">
仅支持 bin, tar, gz, zip 类型的文件,文件大小不能超过1024MB
</span>
</Upload>
</Form.Item>
{file ? (
<Form.Item
style={{
paddingLeft: '16%',
}}
>
<Descriptions size="small" column={1}>
<Descriptions.Item label="文件名">
{file.file.name}
</Descriptions.Item>
<Descriptions.Item label="文件大小">
{transferSize(file.file.size)}
</Descriptions.Item>
<Descriptions.Item label="md5">{file.md5}</Descriptions.Item>
</Descriptions>
</Form.Item>
) : null}
</Form>
</Modal>
);
};