使用react-hooks写法
对antd的Upload.Dragger上传组件
进行二次封装
预期
- 对
antd
的Upload.Dragger组件
进行二次封装,让它的使用方法和Upload.Dragger组件
保持一致。
- 让该组件能自动把数据放到对应后端服务器中。
- 让该组件能的 value 值如果没上传,为数组形式。如果没有值,为空数组。如果有值,都为数组的项。
代码示例
import { InboxOutlined } from "@ant-design/icons";
import { request } from "@umijs/max";
import { Upload } from "antd";
import { UploadProps } from "antd/lib/upload/interface";
import React, { useEffect, useState } from "react";
import { createGlobalStyle } from "styled-components";
const GlobalStyles = createGlobalStyle`
.CustomDraggerUploadContainer {
&.is-the-check {
.ant-upload-drag {
display: none;
}
}
}
`;
interface CustomDraggerUploadProps extends UploadProps {
fileList?: UploadProps["fileList"];
value?: UploadProps["fileList"];
onFileListChange?: (fileList: UploadProps["fileList"]) => void;
noUpload?: boolean;
}
const theFileUpload = `/api/file/upload`;
const CustomDraggerUpload: React.FC<CustomDraggerUploadProps> = (props) => {
const theProps = { ...props };
delete theProps.value;
delete theProps.disabled;
delete theProps.fileList;
delete theProps.onChange;
const [theDisabled, setTheDisabled] = useState(props?.disabled || false);
useEffect(() => {
setTheDisabled(props?.disabled || false);
}, [props?.disabled]);
let [theFileList, setTheFileList] = useState<UploadProps["fileList"]>(
props?.value || []
);
useEffect(() => {
console.log(`props?.value-->`, props?.value);
if (theFileList === props?.value || !props?.value) {
return;
}
setTheFileList(props?.value || []);
}, [props?.value]);
const theUploadProps: UploadProps = {
fileList: theFileList,
progress: {
strokeColor: {
"0%": "#108ee9",
"100%": "#87d068",
},
},
onChange: async (info) => {
if (props?.noUpload) {
console.log(
`不可上传,只能处理onChange: props?.noUpload-->`,
props?.noUpload
);
return;
}
console.log(`列表数据变动事件onChange: info`, info);
setTheFileList(info?.fileList || []);
props?.onChange?.(info?.fileList || []);
},
customRequest: async (theOptions) => {
if (props?.noUpload) {
console.log(
`不可上传,只能处理customRequest: props?.noUpload-->`,
props?.noUpload
);
return;
}
const formData = new FormData();
formData.append("file", theOptions.file, theOptions.file.name);
try {
interface ApiResponse {
code: number;
msg: null | string;
data: {
uuid: string;
sysFileName: string;
sysFileExtension: string;
sysFileSize: number;
sysCreateTime: string;
url: string;
sysFileStoragePath: string;
};
error: boolean;
success: boolean;
}
setTheDisabled(true);
const res = await request<ApiResponse>(theFileUpload, {
data: formData,
method: "POST",
onUploadProgress: (data) => {
console.log(`上传中data`, data);
let params = {
percent: Math.round((data.loaded / data.total) * 100).toFixed(2),
};
theOptions.file.percent = Number(params.percent);
theOptions.file.status = `uploading`;
if (theOptions.file.percent >= 100) {
theOptions.file.status = `done`;
}
const theList = [
theOptions.file,
...theFileList.filter((item) => item.uid !== theOptions.file.uid),
];
theFileList = theList;
setTheFileList(theList);
props?.onChange?.(theList);
theOptions?.onProgress?.(params, theOptions.file);
},
});
console.log(`res`, res);
if (res?.code !== 200) {
throw new Error(`上传不成功`);
}
console.log(
`自定义上传成功: theOptions`,
theOptions,
`\n theFileList`,
theFileList
);
const theList = [
{
...(res?.data || {}),
uid: res?.data?.uuid,
sysFileUuid: res?.data?.uuid,
url: res?.data?.url,
name: res?.data?.sysFileName,
sysFileName: res?.data?.sysFileName,
status: "done",
},
...theFileList.filter((item) => item.uid !== theOptions.file.uid),
];
theFileList = theList;
setTheFileList(theList);
props?.onChange?.(theList);
} catch (error) {
console.log(`error`, error);
theFileList =
theFileList?.filter((item) => item.uid !== theOptions.file.uid) || [];
setTheFileList(theFileList);
props?.onChange?.(theFileList);
} finally {
setTheDisabled(false);
}
},
};
return (
<>
<GlobalStyles />
<Upload.Dragger
{...theUploadProps}
{...theProps}
disabled={theDisabled}
rootClassName={`CustomDraggerUploadContainer ${
theDisabled ? `is-the-check` : ``
}`}
>
{!props?.noUpload && (
<>
<div>
<InboxOutlined />
</div>
<div>单击或拖动文件到此区域进行上传</div>
</>
)}
</Upload.Dragger>
</>
);
};
export default CustomDraggerUpload;
进阶参考
- antd-Upload.Dragger拖拽上传组件;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了