分别设置type、mutiple,accept,且可以绑定ref
-
<div>
选择图片
<input
ref={uploadRef}
type="file"
accept="image/*"
multiple
onChange={handlePictureChange}
/>
div>
Item>
const uploadRef = useRef<any>();
formData.current
const formData = useRef<FormDataProps>(new FormData());
const formData = new FormData();
下面使用的是非标准形式的formdata
const handlePictureChange = (e: any): void => {
console.log(uploadRef.current);//通过current可以拿到files
// debugger;
//定义fileArr数组将files存入该数组
const fileArr = [...uploadRef.current.files];
//对批量上传的图片数量做判断
if (fileArr.length > 200) {
message.error('图片数量较多');
} else {
fileArr.forEach((item: any, index: any) => {
//这是我编写的验证图片格式函数,下面会介绍
const picType = judgePictureType(item.type);
if (picType) {
//图片格式正确
formData.append('file', item)
} else {
message.error('请确保图片格式正确!');
}
});
//下面这段代码可以看到格式正确,且存入了formData
// formData.forEach((value: any, key: any) => {
// console.log(value, key);
// });
}
};
当点击页面的提交button时,下面使用的标准形式的formData
const handleSubmit: React.FormEventHandler<HTMLFormElement> = useCallback(
(e): void => {
e.preventDefault();
validateFields(async (err, values) => {
//判断formdata是否为空
if (!err && formData.current.get('file')) {
try {
// 可以看见formData 的值
formData.current.forEach((value: any, key: any) => {
console.log(value, key);
});
//后端接口
piliaruku(formData.current);
} catch (e) {
message.error(e.message || '添加失败');
}
} else {
message.error('提交格式有误!');
}
});
},
[formData, validateFields],
);
export function judgePictureType(type: string): boolean {
const isJPG = type === 'image/jpeg';
const isPNG = type === 'image/png';
const isBMP = type === 'image/bmp';
const isPic = isJPG || isPNG || isBMP;
return isPic ? true : false;
}
此时,不能使用封装好的post,需要使用axios.post
export async function post<R = any, P = any>(
url: string,
data?: P,
config?: AxiosRequestConfig,
): Promise<ResponseReturn<R>> {
const response = await http.post(url, data, config);
return response.data;
}
import axios from 'axios';
export async function piliaruku(params: any): Promise<ResponseReturn<PliliangrukuResponse>> {
return await axios.post('/piliangruku', params, {
//设置批量上传的请求头
headers: {
'Content-Type': 'multipart/form-data',
},
});
}
export type PliliangrukuResponse = null;
-
<Button>
<Icon type="upload" /> 请选择文件夹
Button>
Upload>
Item>
<Form.Item>
<Button type="primary" htmlType="submit" loading={loading}>
{loading ? '上传中,请不要重复提交' : '提交'}
Button>
Form.Item>
在这里使用beforeUpload对图片做格式判断没有任何意义,如果在uploadProps使用上传函数接口,不管是在beforeUpload还是onChange,都会上传。
举个例子,假如要求图片不超过200,你可以在beforeUpload中使用fileList进行判断,但是如果文件夹中有260张,但其实还是对260张进行了暂存。也就是说循环上传无法停止。
const file_list = useRef<any>([]);
const uploadProps = {
accept: 'image/*',
beforeUpload(): boolean {
return false;
},
async onChange(info: UploadChangeParam<UploadFile<any>>): Promise<void> {
if (!info.file) return Promise.reject(new Error('请选择图片'));
try {
file_list.current = info.fileList;
} catch (e) {
console.error(e);
}
},
};
const [loading, setLoading] = useState(false); //loading状态
const [fileNum, setFileNum] = useState(0); //文件总数
const [fileSuccessNum, setFileSuccessNum] = useState(0);//文件成功的数量
const handleSubmit: React.FormEventHandler<HTMLFormElement> = useCallback((e): void => {
e.preventDefault();
setLoading(true); //图片上传开始
if (file_list.current.length > 200) {
message.error('图片数量较多');
return;
}
const fileArr: Promise<ResponseReturn<PliliangrukuResponse>>[] = [];
file_list.current.forEach((file: any) => {
const reg = /(\.png|\.jpg|\.jpeg)$/g;
//判断格式
if (!reg.test(file.name)) {
//我这里设置了一个变量将格式不正确的图片存入这个数组中
const messageErr = file.name + ' 格式不正确';
setErrFile(errFile => [...errFile, messageErr]);
} else {
const formData = new FormData();
formData.append('file', file.originFileObj);
//后端接口
fileArr.push(pilianrukuXunhuan(formData));
}
});
setFileNum(fileArr.length); //总数
Promise.all(fileArr)
.then(res => {
setFileSuccessNum(res.length); //上传成功的数量
setLoading(false); //图片上传结束
setConfirmModal(true);
})
.catch(e => {
message.error(e);
})
.finally(() => {
setLoading(false);//图片上传失败的状态
});
}, []);
因为图片上传函数使用了promise封装,所以对后端提交函数做了部分修改
export async function pilianrukuXunhuan(params: any): Promise<ResponseReturn<PliliangrukuResponse>> {
const res: any = await axios.post('/..../piliangruku', params, {
headers: {
'Content-Type': 'multipart/form-data',
},
});
if (res.status === 200 && res.data.code === 0) {
return Promise.resolve(res.data);
}
return Promise.reject(new Error('上传出错'));
}