使用 Ant Design 的 Upload 组件实现图片
文章目录
- 使用 Ant Design 的 Upload 组件实现图片
- Upload组件
- itemRender
- 自定义上传列表项的渲染方式
- 修改图片名
- 上传
- 图片上传链接中添加 Bearer Token 的请求头
- onPreview={handlePreview}
- 上传成功后,如何隐藏上传列表
使用 Ant Design 的 Upload 组件实现图片
Upload组件
官方: https://4x.ant.design/components/upload-cn/
Upload上传
文件选择上传和拖拽上传控件。
何时使用#
上传是将信息(网页、文字、图片、视频等)通过网页或者上传工具发布到远程服务器上的过程。
- 当需要上传一个或一些文件时。
- 当需要展现上传的进度时。
- 当需要使用拖拽交互时。
itemRender
itemRender 是 Upload 组件的一个配置项,用于自定义上传列表项的渲染方式。
该配置项接受一个回调函数,函数的参数包括:
originNode:原始的上传列表项节点,即默认的上传列表项。
file:当前的文件对象,包含文件的信息,例如 uid、name、status、url 等属性。
fileList:当前的文件列表,是一个对象数组。
actions:包含三个函数的对象,用于执行下载、预览和删除等操作。
回调函数需要返回一个 React 组件,作为自定义的上传列表项的节点。
通过使用 itemRender 配置项,您可以根据自己的需求和设计,自定义上传列表项的样式和功能。例如,您可以添加额外的操作按钮、显示文件的描述信息、调整上传列表项的布局等。
customItemRender 函数接收 originNode、file、fileList 和 actions 参数,根据这些参数自定义了一个上传列表项的渲染。渲染结果是一个带有文件名、描述信息和操作按钮的自定义上传列表项。
import { PlusOutlined } from '@ant-design/icons';
import { Modal, Upload, Button, message } from 'antd';
import type { RcFile, UploadProps } from 'antd/es/upload';
import type { UploadFile } from 'antd/es/upload/interface';
import React, { useState } from 'react';const getBase64 = (file: RcFile): Promise<string> =>new Promise((resolve, reject) => {const reader = new FileReader();reader.readAsDataURL(file);reader.onload = () => resolve(reader.result as string);reader.onerror = (error) => reject(error);});const App: React.FC = () => {const [previewOpen, setPreviewOpen] = useState(false);const [previewImage, setPreviewImage] = useState('');const [previewTitle, setPreviewTitle] = useState('');const [fileList, setFileList] = useState<UploadFile[]>([{uid: '-1',name: 'image1.png',status: 'done',url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',description: '这是第一张图片',},{uid: '-2',name: 'image2.png',status: 'done',url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',description: '这是第二张图片',},// 添加更多的图片项...]);const handleCancel = () => setPreviewOpen(false);const handlePreview = async (file: UploadFile) => {if (!file.url && !file.preview) {file.preview = await getBase64(file.originFileObj as RcFile);}setPreviewImage(file.url || (file.preview as string));setPreviewOpen(true);setPreviewTitle(file.name || file.url!.substring(file.url!.lastIndexOf('/') + 1));};const handleChange: UploadProps['onChange'] = ({ fileList: newFileList }) =>setFileList(newFileList);const handleEditDescription = (fileUid: string, newDescription: string) => {const updatedFileList = fileList.map((file) => {if (file.uid === fileUid) {return {...file,description: newDescription,};}return file;});setFileList(updatedFileList);};const beforeUpload = (file: RcFile) => {const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';if (!isJpgOrPng) {message.error('只支持上传 JPG/PNG 格式的图片!');}const isLt2M = file.size / 1024 / 1024 < 2;if (!isLt2M) {message.error('图片大小不能超过 2MB!');}return isJpgOrPng && isLt2M;};const uploadButton = (<div><PlusOutlined /><div style={{ marginTop: 8 }}>Upload</div></div>);return (<><Uploadaction="https://www.mocky.io/v2/5cc8019d300000980a055e76"listType="picture-card"fileList={fileList}onPreview={handlePreview}onChange={handleChange}beforeUpload={beforeUpload}>{fileList.length >= 8 ? null : uploadButton}</Upload><Modal open={previewOpen} title={previewTitle} footer={null} onCancel={handleCancel}><img alt="example" style={{ width: '100%' }} src={previewImage} /></Modal></>);
};export default App;
报错:Type ‘{ uid: string; name: string; status: “done”; url: string; description: string; }’ is not assignable to type ‘UploadFile’.
Object literal may only specify known properties, and ‘description’ does not exist in type ‘UploadFile’.ts(2322)
(property) description: string
报错提示显示 description 字段在类型 UploadFile 中不存在。这是因为 UploadFile 类型并没有定义 description 字段。
为了解决这个问题,您可以创建一个新的类型,扩展自 UploadFile,并添加 description 字段。
interface CustomUploadFile extends UploadFile {
description: string;
}
将 fileList 的类型更改为 CustomUploadFile[],并相应地更新 fileList 的初始值:
const [fileList, setFileList] = useState<CustomUploadFile[]>([
{
uid: ‘-1’,
name: ‘image1.png’,
status: ‘done’,
url: ‘https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png’,
description: ‘这是第一张图片’,
},
{
uid: ‘-2’,
name: ‘image2.png’,
status: ‘done’,
url: ‘https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png’,
description: ‘这是第二张图片’,
},
// 添加更多的图片项…
]);
在这段代码中,我添加了一个新的类型 CustomUploadFile,扩展自 UploadFile 并添加了 description 字段。然后,将 fileList 的类型更改为 CustomUploadFile[]。同时,我更新了相关的函数声明和事件处理函数,以适应新的类型。
自定义上传列表项的渲染方式
react源码中:
export type ItemRender<T = any> = (originNode: React.ReactElement, file: UploadFile, fileList: Array<UploadFile>, actions: {
download: () => void;
preview: () => void;
remove: () => void;
}) => React.ReactNode;
列表项的 只有下载、预览、删除
修改图片名
每个上传文件项下方添加了一个输入框,用于编辑文件名。当输入框的值发生变化时,会调用 handleEditDescription 函数来更新文件列表中对应文件项的名称。
我们将 listType 属性设置为 “text”,以显示文件名。然后,通过 itemRender 属性来自定义上传列表项的渲染方式。
将 listType 属性设置为 “text”,以显示文件名。然后,通过 itemRender 属性来自定义上传列表项的渲染方式。
同时,您需要添加一个名为 customItemRender 的函数来定义自定义的上传列表项渲染逻辑。请注意,此函数应该放在 App 组件外部。
上传
这里,我们使用action实现,后台action要怎么实现呢?
这里要前端注意几个参数:
name 发到后台的文件参数名 string file
请确保前端和后端的字段名一致,以正确处理文件上传。
图片上传链接中添加 Bearer Token 的请求头
图片上传链接使用的是Bearer Token,怎么添加header?
可以使用 headers 属性来设置上传请求的头部信息
const handleUpload = async (options: any) => {const { file, onSuccess, onError } = options;const formData = new FormData();formData.append('file', file);try {let token = localStorage.getItem('token');if (null === token) {token = '';}const response = await axios.post('/api/v1/imageManage/upload', formData, {headers: {Authorization: `Bearer ${token}`, // 替换为您的 Bearer Token},});onSuccess(response.data);} catch (error) {onError(error);}};
然后,在返回组件中,使用customRequest属性
如果在上传完成后,前端无法看到刚才上传图片的缩略图?
可以检查以下几个方面:
-
确保上传完成后,后端返回的响应数据中包含了正确的文件信息,如文件的 URL 或其他必要的信息。您可以在 handleUpload 函数中的 onSuccess 回调中打印 response.data,确保返回的数据包含了正确的文件信息。
-
确保 fileList 状态中的每个文件对象包含了正确的 url 字段。您可以在 handleUpload 函数中的 onSuccess 回调中,通过修改 fileList 状态,更新上传成功的文件对象的 url 字段,以确保正确显示缩略图。
总结:在自定义上传请求中,您需要在上传成功后,手动更新文件对象的 url 属性或其他属性,以便正确展示上传后的图片。在 handleUpload 函数中,您可以通过调用 onSuccess 回调并传递正确的数据来更新文件对象。
确保在 handleUpload 函数中,根据实际情况更新文件对象的属性,例如 thumbUrl、url 或其他需要展示图片的属性,并在调用 onSuccess 回调时将更新后的文件对象传递给它。
最后发现问题出在我的返回结果上:
{"data": {"description": "","name": "111.jpg","status": "done","url": "/api/v1/imageManage/download?filename=111.jpg"},"errorCode": 0,"msg": "upload successful!"
}
注意:返回回的 url 字段上。url 字段的值是一个下载图片的 URL,而不是直接指向图片资源的 URL。 意思就是 需要一个完整 URL路径(包括http头的那种!!!)
为了在前端正确显示图片,您需要将下载 URL 转换为直接指向图片资源的 URL。您可以在后端代码中进行相应的处理,将 url 字段的值转换为直接指向图片资源的 URL。
onPreview={handlePreview}
它的作用是在点击预览按钮时,展示图片的预览
export interface UploadFile<T = any> {uid: string;size?: number;name: string;fileName?: string;lastModified?: number;lastModifiedDate?: Date;url?: string;status?: UploadFileStatus;percent?: number;thumbUrl?: string;crossOrigin?: React.ImgHTMLAttributes<HTMLImageElement>['crossOrigin'];originFileObj?: RcFile;response?: T;error?: any;linkProps?: any;type?: string;xhr?: T;preview?: string;
}
上传图片返回 data下的字段属性,要是 继承 UploadFile类的这些属性,Ant Design 的 Upload 组件才可以识别使用
上传成功后,如何隐藏上传列表
可以在上传成功后设置一个状态变量,然后在组件中根据该状态变量来控制上传列表的显示与隐藏。
const CustomImageUpload: React.FC<CustomUploadProps> = ({ onUploadSuccess }) => {const [showUploadList, setShowUploadList] = useState(true);const handleUpload = async (options: any) => {// 上传图片的逻辑...// ...// 上传成功后调用回调函数刷新列表onUploadSuccess();// 隐藏上传列表setShowUploadList(false);};// ...return (<><Upload// ...showUploadList={showUploadList} // 根据状态变量控制上传列表的显示与隐藏>{/* ... */}</Upload></>);
};
相关文章:

使用 Ant Design 的 Upload 组件实现图片
文章目录 使用 Ant Design 的 Upload 组件实现图片Upload组件itemRender自定义上传列表项的渲染方式修改图片名上传图片上传链接中添加 Bearer Token 的请求头onPreview{handlePreview}上传成功后,如何隐藏上传列表 使用 Ant Design 的 Upload 组件实现图片 Upload…...

【知识图谱--第二讲知识图谱的表示】
知识图谱的表示 知识表示Knowledge Representation 知识表示方法知识图谱的符号表示基于图的知识表示与建模简单图建模-最简单的无向图有向标记图OWL与Ontology 知识图谱的向量表示 知识表示 Knowledge Representation 知识表示(KR)就是用易于计算机处…...
C语言---计算n的阶乘
阶乘的概念:一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积,且0的阶乘为1,自然数n的阶乘写作n! 。 任何大于等于1 的自然数n 阶乘表示方法: n!123…(n-1)n 或 n!n(n-1)! 0!1 …...

材料非线性Matlab有限元编程:初应力法与初应变法
导读:本文主要围绕材料非线性问题的有限元Matlab编程求解进行介绍,重点围绕牛顿-拉普森法(切线刚度法)、初应力法、初应变法等三种非线性迭代方法的算法原理展开讲解,最后利用Matlab对材料非线性问题有限元迭代求解算法进行实现,展示了实现求解的核心代码。这些内容都将收…...
QT+OSG/osgEarth编译之八十二:osgdb_obj+Qt编译(一套代码、一套框架,跨平台编译,版本:OSG-3.6.5插件库osgdb_obj)
文章目录 一、osgdb_obj介绍二、文件分析三、pro文件四、编译实践一、osgdb_obj介绍 OBJ格式是一种标准的3D模型文件格式,它以纯文本形式存储关于3D模型的信息。这种格式最初由Wavefront Technologies为其高级可视化系统开发,后来被广泛应用于3D软件之间的数据交换。OBJ格式…...

[office] excel求乘积的公式和方法 #媒体#笔记#经验分享
excel求乘积的公式和方法 本文首先给出两个常规的excel求乘积的链接,然后再例举了一个文字和数字在同一单元格里面的excel求乘积的公式写法。 excel求乘积的方法分为两种,第一种是直接用四则运算的*来求乘积,另外一种就是使用PRODUCT乘积函数…...

OpenEuler20.03LTS SP2 上安装 OpenGauss3.0.0 单机部署过程(二)
开始安装 OpenGauss 数据库 3.1.7 安装依赖包 (说明:如果可以联网,可以通过网络 yum 安装所需依赖包,既可以跳过本步骤。如果网络无法连通,请把本文档所在目录下的依赖包上传到服务器上,手工安装后,即无需通过网络进行 Yum 安装了): 上传:libaio-0.3.111-5.oe1.x8…...

从零开始手写mmo游戏从框架到爆炸(十)— 集成springboot-jpa与用户表
导航:从零开始手写mmo游戏从框架到爆炸(零)—— 导航-CSDN博客 集成springboot-jpa,不用mybatis框架一个是方便对接不同的数据源。第二个目前规划的游戏内容可能对数据库的依赖不是很大,jpa应该肯定能满足要求了…...

Python算法题集_两两交换链表中的节点
Python算法题集_两两交换链表中的节点 题24:两两交换链表中的节点1. 示例说明2. 题目解析- 题意分解- 优化思路- 测量工具 3. 代码展开1) 标准求解【四节点法】2) 改进版一【列表操作】3) 改进版二【三指针法】4) 改进版三【递归大法】 4. 最优算法 本文为Python算法…...

米贸搜|Facebook在购物季使用的Meta广告投放流程
一、账户简化 当广告系列开始投放后,每个广告组都会经历一个初始的“机器学习阶段”。简化账户架构可以帮助AI系统更快获得广告主所需的成效。例如: 每周转化次数超过50次的广告组,其单次购物费用要低28%;成功结束机器学习阶段的…...

前端滚动组件分享
分享一个前端可视化常用的卡片列表滚动组件,常用于可视化项目左右两侧的卡片列表的滚动。效果如下图所示: 组件描述 当鼠标移入滚动区域时,滚动行为停止当鼠标再次离开时,滚动继续 源码展示 <template><div ref"…...

【linux开发工具】vim详解
📙 作者简介 :RO-BERRY 📗 学习方向:致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 📒 日后方向 : 偏向于CPP开发以及大数据方向,欢迎各位关注,谢谢各位的支持 “学如逆水行舟࿰…...

Compose | UI组件(十四) | Navigation-Data - 页面导航传递数据
文章目录 前言传参流程实例说明普通方式传值定义接受参数格式定义接受参数类型获取参数传入参数传参和接受参数效果图 结合 ViewModel 传递参数定义ViewModel在 navigation 定义 ViewModel 实例,并且传入 LoginScreen传入输入框中的值,并且跳转传值获取值…...

部署一个在线OCR工具
效果 安装 1.拉取镜像 # 从 dockerhub pull docker pull mmmz/trwebocr:latest 2.运行容器 # 运行镜像 docker run -itd --rm -p 10058:8089 --name trwebocr mmmz/trwebocr:latest 使用 打开浏览器输入 http://192.168.168.110:10058/ 愉快滴使用吧...

【北邮鲁鹏老师计算机视觉课程笔记】01 introduction
1 生活中的计算机视觉 生活中的各种计算机视觉识别系统已经广泛地应用起来了。 2 计算机视觉与其他学科的关系 认知科学和神经科学是研究人类视觉系统的,如果能把人类视觉系统学习得更好,可以迁移到计算机视觉。是计算机视觉的理论基础。 算法、系统、框…...

maven依赖报错处理(或者maven怎么刷新都下载不了依赖)
maven依赖报错,或者不报错,但是怎么刷新maven都没反应,可以试一下以下操作 当下载jar的时候,如果断网,或者连接超时的时候,会自动在文件夹中创建一个名为*lastupdate的文件,当有了这个文件之后…...

[VulnHub靶机渗透] dpwwn: 1
🍬 博主介绍👨🎓 博主介绍:大家好,我是 hacker-routing ,很高兴认识大家~ ✨主攻领域:【渗透领域】【应急响应】 【python】 【VulnHub靶场复现】【面试分析】 🎉点赞➕评论➕收藏…...

Android14音频进阶:MediaPlayerService如何启动AudioTrack 下篇(五十六)
简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒体系统工程师系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只…...
Python基础篇_修饰符(Decorators)【下】
上一篇:Python基础篇_修饰符(Decorators)【中】property、<attribute_name>.setter、<attribute_name>.deleter、functools.lru_cache(maxsizeNone) Python基础篇_修饰符(Decorators)【下】 Python基础篇_…...

C#,十进制展开数(Decimal Expansion Number)的算法与源代码
1 十进制展开数 十进制展开数(Decimal Expansion Number)的计算公式: DEN n^3 - n - 1 The decimal expansion of a number is its representation in base -10 (i.e., in the decimal system). In this system, each "decimal place…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...

回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...

淘宝扭蛋机小程序系统开发:打造互动性强的购物平台
淘宝扭蛋机小程序系统的开发,旨在打造一个互动性强的购物平台,让用户在购物的同时,能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机,实现旋转、抽拉等动作,增…...