使用react-hooks写法antd的Upload.Dragger上传组件进行二次封装

预期

  1. antdUpload.Dragger组件进行二次封装,让它的使用方法和Upload.Dragger组件保持一致。
  2. 让该组件能自动把数据放到对应后端服务器中。
  3. 让该组件能的 value 值如果没上传,为数组形式。如果没有值,为空数组。如果有值,都为数组的项。

代码示例

// CustomDraggerUpload.tsx

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 styled from 'styled-components';
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);
// 父组件在onChange事件中,大概率会把传出的theFileList赋值给porps.fileList中,防止死循环;
if (theFileList === props?.value || !props?.value) {
return;
}
setTheFileList(props?.value || []);
}, [props?.value]); // useEffect(() => {
// // 这个是为了给父组件传一个onChange事件; // if (theFileList === props?.value) {
// return;
// } // props?.onChange?.(theFileList); //兼容antd的校验机制;
// }, [theFileList]); 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 || []); //兼容antd的校验机制;
},
customRequest: async (theOptions) => {
if (props?.noUpload) {
console.log(
`不可上传,只能处理customRequest: props?.noUpload-->`,
props?.noUpload
); return;
} const formData = new FormData();
// console.log(`自定义上传事件: theOptions`, theOptions);
formData.append("file", theOptions.file, theOptions.file.name);
try {
// 这个接口是后端给的,用于把文件上传到后端的服务器;
interface ApiResponse {
code: number; // 状态码;
msg: null | string; // 消息,可以为 null 或字符串;
data: {
uuid: string; // 文件 UUID;
sysFileName: string; // 文件名;
sysFileExtension: string; // 文件扩展名;
sysFileSize: number; // 文件大小(字节);
sysCreateTime: string; // 文件创建时间;
url: string; // 文件绝对URL;
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 { total, loaded } = 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`;
}
// console.log(`theOptions.file`, theOptions.file); const theList = [
theOptions.file,
...theFileList.filter((item) => item.uid !== theOptions.file.uid),
];
theFileList = theList;
setTheFileList(theList);
props?.onChange?.(theList); //兼容antd的校验机制;
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); //兼容antd的校验机制;
} catch (error) {
console.log(`error`, error);
theFileList =
theFileList?.filter((item) => item.uid !== theOptions.file.uid) || [];
setTheFileList(theFileList);
props?.onChange?.(theFileList); //兼容antd的校验机制;
} finally {
setTheDisabled(false);
}
},
}; // console.log(`上传组件: props-->`, props);
// console.log(`上传组件: theFileList-->`, theFileList); 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;

进阶参考

  1. antd-Upload.Dragger拖拽上传组件;

使用`react-hooks写法`对`antd的Upload.Dragger上传组件`进行二次封装的更多相关文章

  1. 【antd Vue】封装upload图片上传组件(返回Base64)

    最近需要把上传的图片信息存储到数据库,以base64的方式,需要重新封装一下antd的upload组件 1. 使用方法 引入组件然后配置一下即可使用,配置项包括 defaultImageList,需要 ...

  2. jQuery File Upload 文件上传插件使用二 (功能完善)

    使用Bootstrap美化进度条 Bootstrap现在几乎是人尽皆知了,根据它提供的进度条组件, 让进度条显得高大尚点 正因为其功能强大,js模块文件之间牵连较深 不好的地方耦合度非常高 重要的参数 ...

  3. 页面中使用多个element-ui upload上传组件时绑定对应元素

    elemet-ui里提供的upload文件上传组件,功能很强大,能满足单独使用的需求,但是有时候会存在多次复用上传组件的需求,如下图的样子,这时候就出现了问题,页面上有多个上传组件时,要怎么操作呢? ...

  4. 封装react antd的upload上传组件

    上传文件也是我们在实际开发中常遇到的功能,比如上传产品图片以供更好地宣传我们的产品,上传excel文档以便于更好地展示更多的产品信息,上传zip文件以便于更好地收集一些资料信息等等.至于为何要把上传组 ...

  5. 封装Vue Element的upload上传组件

    本来昨天就想分享封装的这个upload组件,结果刚写了两句话,就被边上的同事给偷窥上了,于是在我全神贯注地写分享的时候他就神不知鬼不觉地突然移动到我身边,腆着脸问我在干啥呢.卧槽你妈,当场就把我吓了一 ...

  6. 基于Node的React图片上传组件实现

    写在前面 红旗不倒,誓把JavaScript进行到底!今天介绍我的开源项目 Royal 里的图片上传组件的前后端实现原理(React + Node),花了一些时间,希望对你有所帮助. 前端实现 遵循R ...

  7. 分享一个react 图片上传组件 支持OSS 七牛云

    react-uplod-img 是一个基于 React antd组件的图片上传组件 支持oss qiniu等服务端自定义获取签名,批量上传, 预览, 删除, 排序等功能 需要 react 版本大于 v ...

  8. 封装upload文件上传类

    <?php //封装php中的单文件(图片)上传类 /*  //参数1:$file 文件数组  5个属性值 name,type,size,tmp,error   //参数2:文件保存的路径$pa ...

  9. Nginx Upload Module 上传模块

    传统站点在处理文件上传请求时,普遍使用后端编程语言处理,如:Java.PHP.Python.Ruby等.今天给大家介绍Nginx的一个模块,Upload Module上传模块,此模块的原理是先把用户上 ...

  10. element-ui upload组建上传 file-list踩过的坑

    昨天修完了一个上传组件删除时,图片删掉了,但是地址仍然在的bug,今天测试告诉我bug没休掉,what !,昨天修完之后我自测了一下,OK的好吗,但是测试给我演示了一下,问题仍然存在!!!我看了一下调 ...

随机推荐

  1. [转帖]Nginx应用调优案例

    https://bbs.huaweicloud.com/blogs/146367 [摘要] 1 问题背景nginx的应用程序移植到TaiShan服务器上,发现业务吞吐量没有达到硬件预期,需要做相应调优 ...

  2. [转帖]ORACLE USERENV函数

    https://www.cnblogs.com/youngerger/p/8862210.html ORACLE USERENV函数 USERENV返回关于当前会话的信息.此信息可以用于编写一个应用程 ...

  3. 【JS 逆向百例】网洛者反爬练习平台第一题:JS 混淆加密,反 Hook 操作

    关注微信公众号:K哥爬虫,持续分享爬虫进阶.JS/安卓逆向等技术干货! 声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后 ...

  4. 【二】AI Studio 项目详解【VisualDL工具、(二)环境使用说明、(二)脚本任务、图形化任务、在线部署及预测】PARL

    相关文章 [一]-环境配置+python入门教学 [二]-Parl基础命令 [三]-Notebook.&pdb.ipdb 调试 [四]-强化学习入门简介 [五]-Sarsa&Qlear ...

  5. parser.add_argument()用法——命令行选项、参数和子命令解析器

    argparse是一个Python模块:命令行选项.参数和子命令解析器.通过使用这种方法,可以在使用 1.argparse简介: argparse 模块是 Python 内置的一个用于命令项选项与参数 ...

  6. 5.2 Windows驱动开发:内核取KERNEL模块基址

    模块是程序加载时被动态装载的,模块在装载后其存在于内存中同样存在一个内存基址,当我们需要操作这个模块时,通常第一步就是要得到该模块的内存基址,模块分为用户模块和内核模块,这里的用户模块指的是应用层进程 ...

  7. 7.2 通过API创建新进程

    创建新的进程是Windows程序开发的重要部分,它可以用于实现许多功能,例如进程间通信.并行处理等.其中,常用的三种创建进程的方式分别是WinExec().ShellExecute()和CreateP ...

  8. Python 运用zabbix开发简易巡检工具

    利用SSH或者Zabbix监控,配合Django开发框架,改造出属于自己的监控平台,实现包括主机图形,自动发现,计划任务,批量cmd执行,服务监控,日志监控等功能,由于公司机器混乱,基本上市面上的所有 ...

  9. 利用 ASP.NET Core 开发单机应用

    前言 现在是分布式微服务开发的时代,除了小工具和游戏之类刚需本地运行的程序已经很少见到纯单机应用.现在流行的Web应用由于物理隔离天然形成了分布式架构,核心业务由服务器运行,边缘业务由客户端运行.对于 ...

  10. 记录开发中element树形控件数据应用在页面上的相关问题

    业务场景 根据后台返回数据生成角色权限的树形结构.获取节点数据后,当父节点被勾选时,所有的子节点全部被勾选,而实际上后台并没有返回当前父节点的所有子节点的ID,所以应该只有部分子节点被勾选. 下面第一 ...