antd+Vue 3实现table行内upload文件图片上传【超详细图解】

目录

一、背景

二、效果图

三、代码


一、背景

一名被组长逼着干前端的苦逼后端,在一个晴天霹雳的日子,被要求前端订单产品实现上传产品图片并立刻回显图片。

二、效果图

三、代码

<template>
	<a-table :dataSource="dataSource" :columns="columns">
		/** 我这里只举例上传图片的插槽 */
		<template #base64Url="{ record }">
			<a-upload v-model:file-list="record.fileList" name="file" list-type="picture-card" class="product-upload" :show-upload-list="false" action="" @change="
          (file) => {
            return handleChange(file, record);
          }
        " :customRequest="
          (file) => {
            return requestUploadImg(file, record);
          }
        " accept="image/png, image/jpeg, image/jpg" :before-upload="beforeUpload">
				<img v-if="record.base64Url" :src="record.base64Url" />
				<div v-else>
					<loading-outlined v-if="record.loading" class="ant-upload-icon" />
					<div class="ant-upload-text" v-if="record.loading">上传中</div>
					<cloud-upload-outlined v-else class="ant-upload-icon" />
					<div class="ant-upload-text" v-if="!record.loading">支持上传 .jpg .jpeg .png 且小于 2MB 的图片</div>
				</div>
			</a-upload>
		</template>
	</a-table>
</template>
<script lang="ts">
import { LoadingOutlined, CloudUploadOutlined } from '@ant-design/icons-vue';
import { message } from 'ant-design-vue';
import { defineComponent, ref } from 'vue';

interface FileItem {
	uid: string;
	name?: string;
	status?: string;
	response?: string;
	url?: string;
	type?: string;
	size: number;
	originFileObj: any;
}
interface FileInfo {
	file: FileItem;
	fileList: FileItem[];
}
function getBase64(img: Blob, callback: (base64Url: string) => void) {
	const reader = new FileReader();
	reader.addEventListener('load', () => callback(reader.result as string));
	reader.readAsDataURL(img);
}

export default defineComponent({
	components: {
		LoadingOutlined,
		CloudUploadOutlined,
	},
	setup() {
		//这个只要file的状态发生改变就会触发
		const handleChange = (info: FileInfo, record) => {
			if (info.file.status === 'uploading') {
				record.loading = true;
				return;
			}
			if (info.file.status === 'done') {
				// Get this url from response in real world.
				getBase64(info.file.originFileObj, (base64Url: string) => {
					record.base64Url = base64Url;
					record.loading = false;
				});
                message.success('upload success');
			}
			if (info.file.status === 'error') {
				record.loading = false;
				message.error('upload error');
			}
		};
		//这个是上传图片之前的校验,限制图片的格式和大小。也可以在upload标签中使用accept和size设定用户上传时就禁止点击不符合条件的文件
		const beforeUpload = (file: FileItem) => {
			const isJpgOrPng =
				file.type === 'image/jpeg' || file.type === 'image/jpg' || file.type === 'image/png';
			if (!isJpgOrPng) {
				message.error('You can only upload JPG file!');
			}
			const isLt2M = file.size / 1024 / 1024 < 2;
			if (!isLt2M) {
				message.error('Image must smaller than 2MB!');
			}
			return isJpgOrPng && isLt2M;
		};
		//覆盖默认的上传行为,自定义自己的上传实现
		const requestUploadImg = async (info, record) => {
			requestUploadImgApi({ file: info.file })
				.then((res) => {
                    //必须转为blob格式(二进制文件),否则handleChange方法中接收的info.file中没有originFileObj
					const urlData = URL.createObjectURL(info.file); 
                    //必须调用这个方法,否则上传组件的状态将一直是loading状态,传入的res, info.file, record位置不允许改变,且res必须是包含code、data、status、message等信息的responce,而不是data里的数据,否则会一直是error状态或者loading状态
					info.onSuccess(res, info.file, record); 
				})
				.catch((err) => {
					info.onError();
				});
		};
		return {
			dataSource: [
				{
					key: '1',
					name: '产品1',
					desc: '产品描述1',
					base64Url: '',
					fileList: [],
					loading: false,
				},
				{
					key: '2',
					name: '产品2',
					desc: '产品描述2',
					base64Url: '',
					fileList: [],
					loading: false,
				},
			],

			columns: [
				{
					title: '产品名称',
					dataIndex: 'name',
					key: 'name',
				},
				{
					title: '产品描述',
					dataIndex: 'desc',
					key: 'desc',
				},
				{
					title: '产品图片',
					dataIndex: 'base64Url',
					key: 'base64Url',
					slots: { customRender: 'base64Url' }, //这个表示插槽,在html结构中可以自定义样式
				},
				{
					title: '操作',
					dataIndex: 'operation',
					key: 'operation',
					slots: { customRender: 'operation' },
				},
			],
			handleChange,
			beforeUpload,
			requestUploadImg,
		};
	},
});
</script>
<style lang="less">
.product-upload > .ant-upload {
	width: 204px;
	height: 125px;
}
.ant-upload-icon {
	font-size: 30px;
	opacity: 0.5;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/533398.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

前端三剑客 —— JavaScript (第七节)

内容回顾 DOM编程 document对象 有属性 有方法 节点类型 元素节点 属性节点 文本节点 操作DOM属性 DOM对象.属性名称 DOM对象[属性名称] 调用DOM对象的API 操作DOM样式 获取有单位的样式值 标签对象.style.样式名称&#xff0c;这种方式只能操作行内样式。 使用getComputedSty…

[Linux][进程概念][进程优先级]详细解读

目录&#xff09; 0.冯诺依曼体系结构1.操作系统(Operator System)1.概念2.设计OS的目的3.定位4.系统调用和库函数概念5.总结 2.进程1.基本概念2.描述进程 -- PCB3.task_struct内容分类4.组织进程5.查看进程6.通过系统调用获取进程标识符7.通过系统调用创建进程 -- fork初识8.进…

44---MSATA电路设计

视频链接 mSATA & mini-pcie电路设计01_哔哩哔哩_bilibili mSATA电路设计 1、mSATA简介 1.1、mSATA基本介绍 mSATA接口是标准SATA的迷你版本&#xff0c;通过mini PCI-E界面传输信号&#xff0c;传输速度支持1.5Gbps、3Gbps、6Gbps三种模式。mSATA接口的诞生&#xff…

数据可视化的3D问题

三维对象非常流行&#xff0c;但在大多数情况下会对解释图形的准确性和速度产生负面影响。 以下是对涉及 3d 的主要图形类型的回顾&#xff0c;并讨论了它们是否被认为是不好的做法。 1、3D 条形图&#xff1a;不要 这是一个 3d 条形图。 你可能很熟悉这种图形&#xff0c;因为…

自学嵌入式,已经会用stm32做各种小东西了,下一步是什么,研究stm32的内部吗?

是的&#xff0c;深入研究STM32的内部是一个很好的下一步。我这里有一套嵌入式入门教程&#xff0c;不仅包含了详细的视频讲解&#xff0c;项目实战。如果你渴望学习嵌入式&#xff0c;不妨点个关注&#xff0c;给个评论222&#xff0c;私信22&#xff0c;我在后台发给你。 了…

【Vue + keep-alive】路由缓存

一. 需求 列表页&#xff0c;n 条数据项可打开 n 个标签页&#xff0c;同时1条数据项的查看和编辑共用一个标签页。如下所示&#xff1a; 参考 // 主页面 // 解决因 路由缓存&#xff0c;导致 编辑后跳转到该页面 不能实时更新数据 onActivated(() > {getList() })二. 实现…

Java面试题戏剧

目录 第一幕 、第一场&#xff09;某大厦楼下大门前第二场&#xff09;电梯中第三场&#xff09;走廊中 第二幕、第一场&#xff09;公司前台第二场&#xff09;公司卫生间 第三幕、第一场&#xff09;一场异常面试 第四幕 、第一场&#xff09;大厦楼下门口第二场&#xff09;…

实验5 VLAN基础配置

实验5 VLAN基础配置 一、 原理描述二、 实验目的三、 实验内容四、 实验配置五、 实验步骤1.配置IP地址2.检测链路连通性3.创建 VLAN4.配置Access接口5.检验结果6.配置Trunk端口7.检验连通性 一、 原理描述 现代局域网通常配置为等级结构&#xff0c;一个工作组中的主机通过交…

【vue/uniapp】使用 smooth-signature 实现 h5 的横屏电子签名

通过github链接进行下载&#xff0c;然后代码参考如下&#xff0c;功能包含了清空、判断签名内容是否为空、生成png/jpg图片等。 签名效果&#xff1a; 预览效果&#xff1a; 下载 smooth-signature 链接&#xff1a;https://github.com/linjc/smooth-signature 代码参考&a…

流程图步骤条

1.结构 <ul class"stepUl"> <li class"stepLi" v-for"(item, index) in stepList" :key"index"> <div class"top"> <p :class"{active: currentState > item.key}">{{ item.value }}…

ROS机器人未知环境自主探索功能包explore_lite最全源码详细解析(五)

本系列文章主要针对ROS机器人常使用的未知环境自主探索功能包explore_lite展开全源码的详细解析&#xff0c;并进行概括总结。 本系列文章共包含六篇文章&#xff0c;前五篇文章主要介绍explore_lite功能包中 explore.cpp、costmap_tools.h、frontier_search.cpp、costmap_clie…

Canal--->准备MySql主数据库---->安装canal

一、安装主数据库 1.在服务器新建文件夹 mysql/data&#xff0c;新建文件 mysql/conf.d/my.cnf 其中my.cnf 内容如下 [mysqld] log_timestampsSYSTEM default-time-zone8:00 server-id1 log-binmysql-bin binlog-do-db mall # 要监听的库 binlog_formatROW2.启动数据库 do…

汽车4S行业的信息化特点与BI建设挑战

汽车行业也是一个非常大的行业&#xff0c;上下游非常广&#xff0c;像主机厂&#xff0c;上游的零配件&#xff0c;下游的汽车流通&#xff0c;汽车流通之后的汽车后市场&#xff0c;整个链条比较长。今天主要讲的是汽车流通&#xff0c;汽车4S集团。一个汽车4S集团下面授权代…

【CSS】利用Vue实现数字翻滚动画效果

利用Vue实现数字翻滚动画效果 在很多数据可视化的需求中&#xff0c;动态呈现数据变化是一个常见且具有较强视觉冲击力的手段&#xff0c;尤其是数字的实时变化。今天我们将探讨如何使用 Vue.js 和 CSS3 来实现数字的翻滚动画效果&#xff0c;即模拟真实物体在Z轴上翻动的效果…

python使用uiautomator2操作雷电模拟器9并遇到解决adb 连接emulator-5554 unauthorized问题

之前写过一篇文章 python使用uiautomator2操作雷电模拟器_uiautomator2 雷电模拟器-CSDN博客 上面这篇文章用的是雷电模拟器4&#xff0c;雷电模拟器4.0.78&#xff0c;android版本7.1.2。 今天有空&#xff0c;再使用雷电模拟器9&#xff0c;android版本9来测试一下 uiauto…

利用Flexbox和Margin实现智能布局:如何巧妙分配剩余空间,让你的网页设计更上一层楼?

1、演示 2、flex布局 Flex布局是一种用于Web开发的弹性盒子布局模型&#xff0c;它可以让容器内的子元素在空间分配、对齐和排列方面具有更大的灵活性。以下是Flex布局的基本用法&#xff1a; 容器属性&#xff1a; display: flex;&#xff1a;将容器指定为Flex布局。flex-dire…

头歌-机器学习 第9次实验 随机森林

第1关&#xff1a;Bagging 任务描述 本关任务&#xff1a;补充 python 代码&#xff0c;完成 BaggingClassifier 类中的 fit 和 predict 函数。请不要修改 Begin-End 段之外的代码。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a; 什么是 Bagging&#xf…

【IC前端虚拟项目】验证阶段开篇与知识预储备

【IC前端虚拟项目】数据搬运指令处理模块前端实现虚拟项目说明-CSDN博客 从这篇开始进入验证阶段&#xff0c;因为很多转方向的小伙伴是转入芯片验证工程师方向的&#xff0c;所以有必要先做一个知识预储备的说明&#xff0c;或者作为验证入门的一个小指导吧。 在最开始&#…

C++11 设计模式1. 模板方法(Template Method)模式学习。UML图

一 什么是 "模板方法&#xff08;Template Method&#xff09;模式" 在固定步骤确定的情况下&#xff0c;通过多态机制在多个子类中对每个步骤的细节进行差异化实现&#xff0c;这就是模板方法模式能够达到的效果。 模板方法模式属于&#xff1a;行为型模式。 二 &…

vivado 调试核时钟设置指南

调试核时钟设置指南 注释 &#xff1a; 以下章节适用于 7 系列、 UltraScale 和 UltraScale 器件。 Versal 调试核使用基于 AXI 的连接 &#xff0c; 且不受本章中的 时钟设置指南的约束。 Vivado 硬件管理器使用 JTAG 接口来与 Vivado Debug Hub 核进行通信 &#…