先看效果图:
form表单域中数组:
代码示例:
import { Form, message, Upload } from 'antd'
import { PlusOutlined, LoadingOutlined } from "@ant-design/icons";
import { RcFile, UploadChangeParam, UploadFile, UploadProps } from 'antd/lib/upload';
import { useState } from 'react';
import styled from "styled-components"
type uploader_type = { // 组件传参
name: string,
label: string
}
const getBase64 = (img: RcFile, callback: (url: string) => void) => {
const reader = new FileReader();
reader.addEventListener('load', () => callback(reader.result as string));
reader.readAsDataURL(img);
};
const beforeUpload = (file: RcFile) => {
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
if (!isJpgOrPng) {
message.error('You can only upload JPG/PNG file!');
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
message.error('Image must smaller than 2MB!');
}
return isJpgOrPng && isLt2M;
}
export default function Uploader({ name, label }: uploader_type) {
const [loading, setLoading] = useState(false); // 上传状态
const [imageUrl, setImageUrl] = useState<string>(); // 上传成功之后图片的回填地址
const form = Form.useFormInstance()
const normFile = (e: any) => { // form表单值
console.log('Upload event:', e);
if (Array.isArray(e)) {
return e;
}
return e?.file;
};
//自定义文件上传方法,内置参数,这里的上传方法根据个人需求编写
const uploadImage = async (options: any) => {
//在这里执行文件的上传
//上传成功之后可以在此处 将上传成功的地址 设置到form表单域中 form.setFildValue(key,value)
}
const handleChange: UploadProps['onChange'] = async (info: UploadChangeParam<UploadFile>) => {
if (info.file.status === 'uploading') {
setLoading(true);
return;
}
if (info.file.status === 'done') { //判断文件是否上传成功
// Get this url from response in real world.
getBase64(info.file.originFileObj as RcFile, url => {
setLoading(false);
setImageUrl(url);
});
}
};
const uploadButton = (
<div>
{loading ? <LoadingOutlined /> : <PlusOutlined className='jia' />}
<div style={{ marginTop: 8 }}>点击封面</div>
</div>
);
return (
<Styles>
<Form.Item
label={label}
name={name}
rules={[{ required: true, message: `请上传${label}` }]}
valuePropName="file"
getValueFromEvent={normFile}
>
<Upload
action="#"
beforeUpload={beforeUpload}
onChange={handleChange}
customRequest={uploadImage} //设置自定义上传
listType="picture-card"
maxCount={1}
showUploadList={false}
>
{imageUrl ? <img src={imageUrl} alt="avatar" style={{ width: '100%' }} /> : uploadButton}
</Upload>
</Form.Item>
</Styles >
)
}
const Styles = styled.div`
.ant-upload.ant-upload-select-picture-card {
width: 160px;
height: 160px;
border-radius: 16px;
border: 1px dashed #d1d6e4;
overflow:hidden;
}
.ant-upload{
margin-top:0px;
}
img {
width:100%;
height:100%;
}
.jia {
font-size: 12px;
font-family: Inter-Regular, Inter;
font-weight: 400;
color: #7a88b2;
line-height: 17px;
}
span {
font-size: 12px;
font-family: Inter-Regular, Inter;
font-weight: 400;
color: #7a88b2;
line-height: 17px;
margin-top: 10px;
}
`
自定义方法会内置一个options参数,该参数可以设置上传状态,进度值等,有需要的小伙伴可以自行去了解,以便出现自定义方法文件上传成功,但是react组件却一直显示未成功的问题:
上传成功之后,执行:options.onSuccess(),就可以将文件上传状态转为done