Vue3 + ElementPlus 前端实现分片上传

news/2024/4/29 0:09:13/文章来源:https://blog.csdn.net/Lyrelion/article/details/127404500

目录

1. 什么是分片上传

2. 上传组件模板

3. 上传组件逻辑

3.1 基本思路

3.2 选择上传文件

3.3 校验文件是否合法

3.4 文件加密

3.5 合并文件

3.6 文件切片上传

4. 参考文章

4.1 文章链接

4.2 参考文章提到的注意事项

4.2.1 nginx 上传大小限制

4.2.2 大文件下载


1. 什么是分片上传

将 一个文件 切割为 一系列特定大小的 数据片段,将这些 数据片段 分别上传到服务端;

全部上传完成后,再由服务端将这些 数据片段 合并成为一个完整的资源;

上传过程中,由于外部因素(比如网络波动)导致上传中断,下次上传时会保留该文件的上传进度(断点续传);

2. 上传组件模板

包含三部分:

  • 上传组件,使用 el-upload
  • 进度条组件,使用 el-progress
  • 上传完成状态组件,使用 el-input 自定义
 <el-form-item label="上传附件" prop="uploadFile"><el-uploadv-if="!editForm.inlineAppVersionModel.fileName"class="upload-demo"drag:show-file-list="false":action="APP_MANAGEMENT.uploadFile"// 根据项目的接口传递参数:data="{applicationId: applicationId,applicationVersion: applicationVersion,bucketName: 'app'}"// 覆盖默认的http请求:http-request="handleFileUpload"><el-icon class="el-icon--upload"><upload-filled /></el-icon><div v-if="!progress" class="el-upload__text">Drop file here or <em>click to upload</em></div>// 进度条<el-progressv-else:text-inside="true":stroke-width="24":percentage="progress"status="success"/></el-upload>// 上传成功之后隐藏上传文件组件<div v-else style="display: flex;"><el-input v-model="editForm.inlineAppVersionModel.fileName" readonly></el-input><div style="display: flex;"><el-button type="primary" :icon="Download" size="small" @click="handleFileDownload" /><el-button type="primary" :icon="Delete" size="small" @click="handleFileDel" /></div></div></el-form-item>

3. 上传组件逻辑

3.1 基本思路

使用 el-upload 选择文件

选择成功的 回调函数 可以读取文件信息,用于前端校验文件的合法性

前端校验文件合法后,将文件进行切片

通过 请求轮询 把切片传递给后端

3.2 选择上传文件

在这一步,可以获得文件信息

根据文件信息,对文件进行合法性校验

校验成功后,调用文件切片方法

/*** @description: 选择上传文件* @param file el-upload 返回的参数*/
const handleFileUpload = async (file: any) => {console.log('el-upload 返回的参数 === ', file.file);// 如果文件合法,则进行分片上传if (await checkMirrorFile(file)) {// 文件信息const files = file.file;// 从 0 开始的切片const shardIndex = 0;// 调用 文件切片 方法uploadFileSilce(files, shardIndex);// 文件非法,则进行提示} else {ElMessage.error('请检查文件是否合法!');}
};

3.3 校验文件是否合法

校验文件格式

校验文件大小

调用接口,校验磁盘剩余空间大小

/*** @description: 校验文件合法性*/
const checkMirrorFile = async (file) => {// 校验文件格式,支持.zip/.tarconst fileType = file.file.name.split('.')if (fileType[fileType.length - 1] !== 'zip' && fileType[fileType.length - 1] !== 'tar') {ElMessage.warning('文件格式错误,仅支持 .zip/.tar')return false}// 校验文件大小const fileSize = file.file.size;// 文件大小是否超出 2Gif (fileSize > 2 * 1024 * 1024 * 1024) {ElMessage.warning('上传文件大小不能超过 2G')return false}// 调用接口校验文件合法性,比如判断磁盘空间大小是否足够const res = await checkMirrorFileApi()if (res.code !== 200) {ElMessage.warning('暂时无法查看磁盘可用空间,请重试')return false}// 查看磁盘容量大小if (res.data.diskDevInfos && res.data.diskDevInfos.length > 0) {let saveSize = 0res.data.diskDevInfos.forEach(i => {// 磁盘空间赋值if (i.devName === '/dev/mapper/centos-root') {// 返回值为GB,转为字节BsaveSize = i.free * 1024 * 1024 * 1024}})// 上传的文件大小没有超出磁盘可用空间if (fileSize < saveSize) {return true} else {ElMessage.warning('文件大小超出磁盘可用空间容量')return false}} else {ElMessage.warning('文件大小超出磁盘可用空间容量')return false}
}

3.4 文件加密

此处文件上传用 MD5 进行加密,需要安装依赖 spark-md5

npm i spark-md5

/*** @description: 文件加密处理*/
const getMD5 = (file: any): Promise<string> => new Promise((resolve, reject) => {const spark = new SparkMD5.ArrayBuffer();// 获取文件二进制数据const fileReader = new FileReader();fileReader.readAsArrayBuffer(file); // file 就是获取到的文件// 异步执行函数fileReader.addEventListener('load', (e: any) => {spark.append(e.target.result);const md5: string = spark.end();resolve(md5);});fileReader.addEventListener('error', (e) => {reject(e);});
});

3.5 合并文件

通过接口合并上传文件,接口需要的参数:

  • 文件名
  • 文件唯一 hash 值

接口合并完成后,前端展示已上传的文件名称

/*** @description: 合并文件* @param name 文件名* @param hash 文件唯一 hash 值* @return 命名名称*/
const composeFile = async (name: string, hash: string) => {console.log('开始文件合并');const res = await uploadFileMerge({applicationId: props.applicationId,applicationVersion: props.applicationVersion,bucketName: 'app',fileName: name,hash,});console.log('后端接口合并文件 ===', res);if (res.status === 200 && res.data.code) {// 合并成功后,调整已上传的文件名称state.editForm.inlineAppVersionModel.fileName = name;}
};

3.6 文件切片上传

接口轮询 —— 每次携带一个文件切片给后端;后端接受到切片 并 返回成功状态码后,再进行下一次切片上传

/*** @description: 分片函数* @param file 文件* @param shardIndex 分片数量*/
const uploadFileSilce = async (file: File, shardIndex: number) => {// 文件名const { name } = file;// 文件大小const { size } = file;// 分片大小const shardSize = 1024 * 1024 * 5;// 文件加密const hash: string = await getMD5(file);// 分片总数const shardTotal = Math.ceil(size / shardSize);// 如果 当前分片索引 大于 总分片数if (shardIndex >= shardTotal) {isAlive.value = false;progress.value = 100;// 合并文件composeFile(name, hash);return;}// 文件开始结束的位置const start = shardIndex * shardSize;const end = Math.min(start + shardSize, size);// 开始切割const packet = file.slice(start, end);// 拼接请求参数const formData = new FormData();formData.append('file', packet);formData.append('applicationId', props.applicationId);formData.append('applicationVersion', props.applicationVersion);formData.append('bucketName', 'app');formData.append('hash', hash);formData.append('shardSize', shardSize as unknown as string);formData.append('seq', shardIndex as unknown as string);// 如果 当前分片索引 小于 总分片数if (shardIndex < shardTotal) {// 进度条保留两位小数展示progress.value = Number(((shardIndex / shardTotal) * 100).toFixed(2)) * 1;// 调用文件上传接口const res = await uploadFile(formData);if (res.status !== 200) {ElMessage.error('上传失败');progress.value = 0;return;}if (res.status === 200 && res.data.code === 200) {// 这里为所有切片上传成功后进行的操作console.log('上传成功');}// eslint-disable-next-line no-param-reassignshardIndex++;// 递归调用 分片函数uploadFileSilce(file, shardIndex);}};

4. 参考文章

4.1 文章链接

前端大文件上传和下载(分片上传)_BreenCL的博客-CSDN博客_前端分片上传前端大文件上传(分片上传)一、问题日常业务中难免出现前端需要向后端传输大型文件的情况,这时单次的请求不能满足传输大文件的需求,就需要用到分片上传业务需求为:用户可以上传小于20G的镜像文件,并进显示当前上传进度前端:vue3.x+Element Plus组件+axios二、解决解决思路简单为前端选择文件后读取到文件的基本信息,包括:文件的大小、文件格式等信息,用于前端校验,校验完成后将文件进行切片并通过请求轮询把切片传递给后端Vue的元素代码如下,主要借助el-upload组件:&lhttps://blog.csdn.net/baoyin0822/article/details/123922628

4.2 参考文章提到的注意事项

4.2.1 nginx 上传大小限制

nginx 默认上传大小为 1MB,若超过 1MB,则需要修改 nginx 配置 解除上传限制

4.2.2 大文件下载

/*** @description: 动态创建 a 标签,实现大文件下载*/
const downloadMirror = async (item) => {let t = {id: item.id,}const res = await downloadMirrorApi(t)if (res.headers["content-disposition"]) {let temp = res.headers["content-disposition"].split(";")[1].split("filename=")[1]let fileName = decodeURIComponent(temp)// 通过创建a标签实现文件下载let link = document.createElement('a')link.download = fileNamelink.style.display = 'none'link.href = res.data.msgdocument.body.appendChild(link)link.click()document.body.removeChild(link)} else {ElMessage({message: '该文件不存在',type: 'warning',})}
}

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

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

相关文章

Excel中的HLOOKUP、VLOOKUP、XLOOKUP函数

昨天使用INDEX和MATCH两个EXCEL函数完成了表中数据的快速查找&#xff0c;想一想&#xff0c;EXCEL中还有另外的查找函数&#xff0c;比如HLOOKUP、VLOOKUP、LOOKUP、XLOOKUP函数&#xff0c;那使用它们能不能完成同样的操作呢&#xff1f;   可以的。   仍然是昨天的问题&…

window下,cuda版本和NVIDIA驱动版本关系,cuda版本 和 TensorFlow-GPU版本关系,TensorFlow-GPU安装

一、cuda安装&#xff0c;cuda 和 TensorFlow 版本对应&#xff0c;链接https://www.tensorflow.org/install/source#tested_source_configurations 1.查看自己安装的驱动版本, nvidia-smi 2.安装所需要的cuda&#xff0c;下载链接CUDA Toolkit Archive | NVIDIA Developer 找…

微信小程序云开发入门-数据库插入数据(包含批量)

一、前言 文章将介绍如何在微信小程序云开发中向云开发数据库插入数据&#xff08;单条或批量&#xff09;。 写法有好几种&#xff0c;文章将会一一进行对比&#xff0c;看看每种写法之间有何优缺点&#xff0c;如何让代码看起来更优雅。 为了更加贴合实际的开发逻辑&#xf…

Unity重启 --- 工具介绍部分 (面板与工具条)

第一部分 --- Project项目资源面板 1.两类常用文件 --- PNG图像文件和FBX文件&#xff08;游戏模型文件&#xff09; 2.每一个项目文件夹中都会自动创建一个资源Assets文件夹&#xff0c;我们各类美术资源&#xff0c;游戏脚本都是放在这个文件夹中的 3.在Unity中资源文件夹会…

操作系统实验三:死锁避免程序设计

银行家算法&#xff1a;Python模拟与实现一、实验目的二、实验内容三、实验要求四、实验代码结果展示全部代码一、实验目的 1、 理解死锁产生的基本原理&#xff0c;以及死锁的必要条件&#xff1b; 2、 掌握死锁避免的基本原理与思路。 二、实验内容 试利用银行家算法对死锁…

人工神经网络概念及组成,人工神经网络基本结构

1、简述人工神经网络的结构形式 神经网络有多种分类方式&#xff0c;例如&#xff0c;按网络性能可分为连续型与离散型网络&#xff0c;确定型与随机型网络:按网络拓扑结构可分为前向神经网络与反馈神经网络。本章土要简介前向神经网络、反馈神经网络和自组织特征映射神经网络…

postman使用excel参数批量执行

postman使用excel参数批量执行第一步,写好连接,报错。参数使用{{name}},这样的划分。保存接口第二步,找到runner。选择接口所在的文件夹,点击runner 第三步,选择接口和文件 点击run,运行,等待接口执行完成

百多安医疗冲刺科创板:半年营收1亿 为张海军与郭海宏夫妻店

雷递网 雷建平 10月20日山东百多安医疗器械股份有限公司&#xff08;简称&#xff1a;“百多安医疗”&#xff09;日前递交招股书&#xff0c;准备在科创板上市。百多安医疗计划募资7.6亿元&#xff0c;其中&#xff0c;2.64亿元用于医用导管产业化升级项目&#xff0c;2.48亿元…

《软件测试》实验2:嵌入式软件测试实验报告

文章目录实验目的温度控制器需求文档及测试要求环境搭建实验内容温度采集处理功能测试加热棒输出电压测试散热风扇温度传感器输入接口&#xff08;Senser_JK&#xff09;控制加热棒输出接口&#xff08;Heater_JK&#xff09;控制散热风扇输出接口&#xff08;Fan_JK&#xff0…

《设计模式:可复用面向对象软件的基础》——结构型模式(2)(笔记)

文章目录四、结构型模式4.4 DECORATOR(装饰)——对象结构型模式1.意图2.别名补充部分3.动机4.适用性5.结构6.参与者7.协作8.效果9.实现10.代码示例11.相关模式4.5 FACADE&#xff08;外观&#xff09;1.意图2.动机3.适用性4.结构5.参与者6.协作7.效果8.实现9.代码示制10.相关模…

Postgresql中yacc语法树冲突解决方法(shift/reduce conflicts)

处理方法 Postgresql中的gram.y可以独立编译&#xff0c;独立编译可以控制bison的参数来打印具体错误&#xff1a; PG15 cd src/backend/parserbison -d -o gram.c gram.y -Wno-deprecated正常执行后会产生gram.c文件&#xff0c;一旦发生冲突&#xff0c;bison会报错&#…

设计模式—关于如何更好的封装与创建对象

上一节我们主要学习了使用设计模式来写代码的指导思想以及设计模式的分门别类,本节主要学习创建型的三种设计模式是怎么使用的。如何利用创建型设计模式来指导我们更好的封装代码更好的创建对象。 为什么要封装?封装能带给我们什么好处?定义变量不会污染外部:封装的首要目的…

神经网络图像识别技术,神经网络指纹识别

1、声纹识别技术未来的发展趋势如何&#xff1f; 近几年来&#xff0c;我国生物识别技术行业市场主体数量呈迅速增长的趋势&#xff0c;截至目前&#xff0c;行业企业数量超4000家。据统计&#xff0c;2013-2018年&#xff0c;我国生物识别技术行业新增企业数量呈逐年增长的趋…

【编程题】【Scratch四级】2022.06 成绩查询

成绩查询 期末考试结束了,小朋友想知道自己考试的成绩和班级排名,让我们一起来实现这个功能吧! 1. 准备工作 (1)保留默认白色背景和小猫角色; (2)创建名为“姓名”和“成绩”的列表,按照图1输入相关内容。 2. 功能实现 (1)点击小绿旗,小猫询问“你要查询谁的成…

JS(第十课)JS中的对象

Com.Java.Basis第九课 《类与对象》_星辰镜的博客-CSDN博客 有兴趣的可以去看一下 本文内容核心:对象 在百度翻译中对象称为object 安装插件 第一部分去找找在JS中对象的语法是什么 如何去创建对象的&#xff0c;调用对象&#xff01; var name"李四"; var people…

图形学-(视图变换,投影变换)

1.视图变换 在 3 维物体变到二维平面的过程中&#xff0c;我们需要规定好相机的位置。对于相机所做的变换就是视图变换 &#xff08;Viewing/Camera transformation&#xff09;。 我们需要对相机位置进行定义&#xff0c;对于一个相机我们要规定下面三个属性&#xff1a; 相…

Transformer3

又是 一篇关于Transformer的~~ 太多了 本文结合Transformer和ConvNets的优点&#xff0c;构造了一种新的即插即用运算符ParC&#xff0c;可以高效地部署在不同的平台上。一个Trick 搞定 CNN与Transformer&#xff0c;即插即涨点即提速&#xff01; 论文链接&#xff1a;http…

Ansible自动化运维工具介绍与部署

ansible自动化运维工具介绍与部署 文章目录一、什么是自动化运维&#xff1f;二、常用的自动化运维工具2.1 Ansible2.2 SaltStack2.3 Puppet2.4 三种自动化工具特点对比三、介绍Ansible3.1 什么是 Ansible?3.2 Ansible 无需代理3.3 Ansible 方式四、部署Ansible4.1 控制节点4.…

U-BOOT小全(三):SPL框架

1、什么是SPL&#xff1f; 为了可以使已有的所有SPL的设计统一&#xff0c;也为了简化添加适用于新板子的设计&#xff0c;专门设计一个通用的SPL框架。在SPL框架下&#xff0c;一个板子的所有代码都能够被重用。代码复制和链接不再是必要的。 在uboot-2011的/doc/README.spl…

跨境电商必读:什么是社交媒体营销?

关键词&#xff1a;跨境电商&#xff0c;社交媒体营销 社交媒体渠道已迅速成为业务发展战略不可分割的一部分&#xff0c;关于社交媒体如何重塑消费者行为&#xff0c;以及组织如何利用它获得收益&#xff0c;网络上已经有大量相关信息&#xff0c;但仍有许多跨境电商企业难以…