使用`react-hooks写法`对`antd的Upload.Dragger上传组件`进行二次封装
使用react-hooks写法对antd的Upload.Dragger上传组件进行二次封装
预期
- 对
antd的Upload.Dragger组件进行二次封装,让它的使用方法和Upload.Dragger组件保持一致。 - 让该组件能自动把数据放到对应后端服务器中。
- 让该组件能的 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;
进阶参考
使用`react-hooks写法`对`antd的Upload.Dragger上传组件`进行二次封装的更多相关文章
- 【antd Vue】封装upload图片上传组件(返回Base64)
最近需要把上传的图片信息存储到数据库,以base64的方式,需要重新封装一下antd的upload组件 1. 使用方法 引入组件然后配置一下即可使用,配置项包括 defaultImageList,需要 ...
- jQuery File Upload 文件上传插件使用二 (功能完善)
使用Bootstrap美化进度条 Bootstrap现在几乎是人尽皆知了,根据它提供的进度条组件, 让进度条显得高大尚点 正因为其功能强大,js模块文件之间牵连较深 不好的地方耦合度非常高 重要的参数 ...
- 页面中使用多个element-ui upload上传组件时绑定对应元素
elemet-ui里提供的upload文件上传组件,功能很强大,能满足单独使用的需求,但是有时候会存在多次复用上传组件的需求,如下图的样子,这时候就出现了问题,页面上有多个上传组件时,要怎么操作呢? ...
- 封装react antd的upload上传组件
上传文件也是我们在实际开发中常遇到的功能,比如上传产品图片以供更好地宣传我们的产品,上传excel文档以便于更好地展示更多的产品信息,上传zip文件以便于更好地收集一些资料信息等等.至于为何要把上传组 ...
- 封装Vue Element的upload上传组件
本来昨天就想分享封装的这个upload组件,结果刚写了两句话,就被边上的同事给偷窥上了,于是在我全神贯注地写分享的时候他就神不知鬼不觉地突然移动到我身边,腆着脸问我在干啥呢.卧槽你妈,当场就把我吓了一 ...
- 基于Node的React图片上传组件实现
写在前面 红旗不倒,誓把JavaScript进行到底!今天介绍我的开源项目 Royal 里的图片上传组件的前后端实现原理(React + Node),花了一些时间,希望对你有所帮助. 前端实现 遵循R ...
- 分享一个react 图片上传组件 支持OSS 七牛云
react-uplod-img 是一个基于 React antd组件的图片上传组件 支持oss qiniu等服务端自定义获取签名,批量上传, 预览, 删除, 排序等功能 需要 react 版本大于 v ...
- 封装upload文件上传类
<?php //封装php中的单文件(图片)上传类 /* //参数1:$file 文件数组 5个属性值 name,type,size,tmp,error //参数2:文件保存的路径$pa ...
- Nginx Upload Module 上传模块
传统站点在处理文件上传请求时,普遍使用后端编程语言处理,如:Java.PHP.Python.Ruby等.今天给大家介绍Nginx的一个模块,Upload Module上传模块,此模块的原理是先把用户上 ...
- element-ui upload组建上传 file-list踩过的坑
昨天修完了一个上传组件删除时,图片删掉了,但是地址仍然在的bug,今天测试告诉我bug没休掉,what !,昨天修完之后我自测了一下,OK的好吗,但是测试给我演示了一下,问题仍然存在!!!我看了一下调 ...
随机推荐
- jcmd的简要分析命令
jcmd的简要分析命令 背景 端午加班一整天. 回到家同事让他们抓取一下堆栈信息好进行分析 连上VPN后就进行了一下处理. 自己简单看了下堆栈的总数等信息. 同事使用工具进行了分析. 我这边其实下过很 ...
- Redis monitor命令
MONITOR Syntax MONITOR Available since: 1.0.0 Time complexity: ACL categories: @admin, @slow, @dange ...
- CentOS8 安装 SQLSERVER2019的简单过程
1. 获取rpm包直接从微软官方网站即可 -rw-r--r-- 1 root root 820984 Apr 5 22:23 msodbcsql17-17.5.2.1-1.x86_64.rpm -rw ...
- Redis-rdb-tools与rdr工具学习与使用
Redis-rdb-tools与rdr工具学习与使用 简要说明 rdb工具是python写的一套工具,可以分析dump文件,获取key等信息. rdb其实有一套rdb-profiler工具, 能够导出 ...
- 热更新适配ibatis原理浅析
一.热更新解决了什么问题? 在研发过程中,每个研发同学在联调.自测阶段中总会频繁的去执行编译.构建.打包的动作,遇到比较大的项目,执行一套流程下来,往往需要3-10分钟左右,极大的降低了研发的速度,基 ...
- ElasticSearch集群灾难:别放弃,也许能再抢救一下 | 京东云技术团队
1 前言 Elasticsearch作为一个分布式搜索引擎,自身是高可用的:但也架不住一些特殊情况的发生,如: 集群超过半数的master节点丢失,ES的节点无法形成一个集群,进而导致集群不可用: ...
- How to Use Github
C:\Windows\System32\drivers\etc\hosts 在最后加上一句 20.205.243.166 github.com 从 https://ping.chinaz.com/ 来 ...
- css3中的圆角border-radius
css3的属性应该加上浏览器前缀 不同的浏览器内核不同,因此css的前缀不同. 常见的几种浏览器内核 火狐浏览器 Geoko内核 前缀是 -mox- 谷歌浏览器, Webkit内核 前缀是 -wekb ...
- 【0基础学爬虫】爬虫基础之自动化工具 Selenium 的使用
大数据时代,各行各业对数据采集的需求日益增多,网络爬虫的运用也更为广泛,越来越多的人开始学习网络爬虫这项技术,K哥爬虫此前已经推出不少爬虫进阶.逆向相关文章,为实现从易到难全方位覆盖,特设[0基础学爬 ...
- 在mac中双击执行python
执行python脚本 mac有内置的python,但还是建议你自己安装一个python,如果没有卸载mac自带的python2.7,当你需要使用python3执行脚本时,python命令需要改为pyt ...