使用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. [转帖]01-rsync备份方式

    https://developer.aliyun.com/article/885783?spm=a2c6h.24874632.expert-profile.284.7c46cfe9h5DxWK 简介: ...

  2. [译]深入了解现代web浏览器(四)

    本文是根据Mariko Kosaka在谷歌开发者网站上的系列文章https://developer.chrome.com/blog/inside-browser-part4/翻译而来,共有四篇,该篇是 ...

  3. It is currently in use by another Gradle instance

    FAILURE: Build failed with an exception. * What went wrong: Could not create service of type TaskHis ...

  4. express实现批量删除和分页

    后端代码批量删除 // 批量删除 router.get('/manyDel', function (req, res) { let { ids } = req.query if (ids&&a ...

  5. vite配置开发环境和生产环境

    为什么需要境变量的配置 在很多的时候,我们会遇见这样的问题. 开发环境的接口是:http://test.com/api 但是我们的生产环境地址是:http://yun.com/api 此时,我们打包的 ...

  6. 将地址栏的参数变成json序列化。

    将地址栏的参数变成json序列化. GetQueryJson1 () { let url = this.$route.query.redirect; // 获取当前浏览器的URL (redirect= ...

  7. Git - 关联远程仓库以及同时使用Lab和Hub

    更新一下,感觉有更简单的方式 就比如你git config 的 全局的name和email是lab的 那就clone github上的项目然后设置局部的name和email就行了 ********** ...

  8. P9110 [PA2020] Samochody dostawcze

    题目简述 有 \(n\) 个点,这些点分为两种类型.第一种,点在 \((x,0)\) 的位置.这些点从 \(t_i\) 的时刻开始向北走.第二种,点在 \((0,y)\) 的位置.这些点从 \(t_i ...

  9. 基于OpenIM 实现聊天机器人功能

    ### 简要描述 使用 OpenIM 中的 Webhook 机制实现聊天机器人功能.发送文本消息或图片消息给聊天机器人后,机器人会返回相同的消息.开发者可以替换此逻辑,在LangChain框架上调用L ...

  10. Leetcode 92题反转链表 II(Reverse Linked List II) Java语言求解

    前言 反转链表可以先看我这篇文章: Leetcode 206题 反转链表(Reverse Linked List)Java语言求解 题目链接 https://leetcode-cn.com/probl ...