el-upload多文件上传;el-upload采用递归依次上传文件;el-upload采用递归在上一个文件上传成功后再传下一个文件

场景: 需求是接口一次上传一个文件,前一个文件上传成功后再调下一个接口上传下一个文件
el-upload本身就支持多文件上传。但是它是并发进行,例如:选择一千个文件后,是一千个文件自动立马并行调用一千个后端接口去上传。这样容易把服务器搞爆。
.
网上还有,将一千个文件放在一个接口里上传。这一样也容易把服务器搞爆 (具体看下方逻辑详解第4点)
.
我采用的是一次选择一千个文件后, 递归先上传第一个文件,第一个接口上传成功或者失败后,再调后端第二个接口上传第二个文件,依次等待上传完一千个文件(具体看下方逻辑详解第4点)。 这样优缺点就是:上传时间比较长,需要等前一个传好才会进行下一个,但是这样服务器压力小不会爆掉。

在这里插入图片描述

主要逻辑详解:
1.属性:auto-upload=“false” ,设置fallse否后,就阻止了文件的立即上传功能了,变成手动或者调用接口上传。之前一次选择1000个后会立即调用1000个接口就是立即上传导致的。
.
2.属性:auto-upload=“false” ,设置fallse否后,原来的上传前和上传成功事件就都不会触发了,action好像也无效了,只会触发上传change事件、上传失败事件、和上传个数超限事件
.
3.注意change事件,一次选了1000条后,change事件也会执行1000次(第一次是1个文件、第二次是两个文件、第1000次拿到1000个文件…),所以我在这里写了个防抖事件time。通过防抖,可以知道什么时候,change事件结束了,也就知道什么时候拿到了所有的文件。此时就可以去做上传调后端接口的功能了。
.
4.因为我是想减少服务器压力,既在上一个文件上传结束后,再去上传下一个文件。故,我采用了递归一次传一个(递归逻辑在submitUpload2事件里)。同样的,如果你想只调用一次接口,将1000个文件传给后端,那么你就将submitUpload2递归事件给修改调,改成调一次接口,传所有file文件数组即可(具体看你们后端的数据结构)。
.
5.因为是上传多个文件,时间肯定长,如果你不想继续传递后续文件,就调用submitAbort即可。但是element文档说的abort()取消上传事件不生效。所以我是直接将上传列表给置空了,所以递归也就结束了就不传递了。
.
6.同样因为上传时间长,我就设置了进度条(当前已上传的个数/所有需要上传个数)。但是你如果切换到其他页面的话,再切换到当前上传vue页面,因为生命周期原因导致看不到上传进度。所以可以将这个上传vue页面使用keep-alive进行路由缓存,这样除了刷新浏览器外,切换到当前页还是会读缓存会看到上传进度。(如果你既想要缓存进度条,又想要刷新页面的list等某些数据,那么你缓存此页面,然后在activated单独调获取list数据方法即可)。
.
7.因为我的需要是,选择文件成功后,默认去上传,所以我是在防抖事件后就去调递归上传了。正常情况下,其实需要点击这个按钮然后去上传的,既手动点击上传(被注释掉了)<!-- <el-button style="margin-left: 10px;" size="small" type="success" @click="submitUpload2">手动点击上传</el-button> -->

以下代码可直接复制使用(注意将axios的接口上传地址改成自己的)!

<template><div class="group_insurance_order1" style="padding-top:100px;"><!--:auto-upload="false" 是否在选取文件后立即进行上传 false阻止自动上传 -- 且上传前和上传成功的事件都不会再触发 只会触发@change事件了:http-request="uploadFile"  覆盖默认的上传行为,可以自定义上传的实现(this.$refs.upload1.submit()  会触发调用uploadFile函数)--><el-upload ref="upload1" class="upload-demo" action="/chc-shop/api/v1/accident/szcp/electronicfile/upload" accept=".pdf" :disabled="disabledUpload" :auto-upload="false" :on-change="changeFile" :on-error='fileErr' :on-exceed="handleExceed" :file-list="fileList1" :before-upload="beforeAvatarUpload" :on-success="msgSuccessOne" :data="fileData" list-type="picture" drag :show-file-list="false" :multiple="true" :limit="1000"><i class="el-icon-upload"></i><div class="el-upload__text" style="margin-top: -10px;line-height: 20px;">将文件拖到此处,<em v-if="!disabledUpload">或点击上传(单个文件需小于100M,一次最多上传1000个pdf文件)</em><em v-else>(文件正在上传中,请等待...</em></div></el-upload><div><!-- <el-button style="margin-left: 10px;" size="small" type="success" @click="submitUpload2">手动点击上传</el-button> --><el-button v-if="showPercent" style="margin-left: 10px;" size="small" type="success" @click="submitAbort">取消后续文件上传</el-button></div><div style="color:orange;" v-if="showPercent">上传过程请勿刷新浏览器和跳转其他页面...</div><!-- 进度条 --><el-progress v-if="showPercent" :percentage="Number((percentNow*100/percentTotal).toFixed(0))"></el-progress></div>
</template><script>
import axios from 'axios'
export default {data () {return {fileNum: '',  // 单词递归上传的文件upFileList: '',//需要依次上传的待传列表percentTotal: 0,//总上传个数percentNow: 0,//当前上传个数showDesc: '',//结束文案showPercent: false,//显示上传进度条time: null,// change事件是否结束 是否可以直接调手动上传事件(目前设置1.5s)disabledUpload: false,//正在上传中 禁止再次选择文件上传fileData: {},//上传参数fileList1: [],}},activated: {// 对于每次进入页面想要刷新的数据,放在这里调用即可 例如 this.getList()},methods: {// 超出限制个数提示handleExceed (files, fileList) {console.log('当前限制一次性最多上传1000个文件', files, fileList)this.$message.warning("当前限制一次性最多上传1000个文件")},changeFile (file, fileList) {this.disabledUpload = trueconsole.log('changeFile', file, fileList)const isLt2M = file.size / 1024 / 1024 < 100if (!isLt2M) {this.$message.warning('上传文件大小不能超过 100M')// return false // 这个return无效 故去掉}if (!(file.name.indexOf('.pdf') > -1)) {this.$message.warning("当前仅支持pdf格式的文件上传")// return false // 这个return无效 故去掉}// 符合条件的进入待传列表this.upFileList = []for (let x of fileList) {if (x.raw && (x.name.indexOf('.pdf') > -1) && (x.size / 1024 / 1024 < 100)) {// 过滤掉非pdf 和小于100M的this.upFileList.push(x.raw)this.percentTotal = this.upFileList.lengththis.percentNow = 0this.showPercent = falsethis.showDesc = ''}}clearTimeout(this.time)this.time = setTimeout(() => {this.time = nullconsole.log('防抖 高频触发后n秒内只会执行一次  再次触发重新计时')this.fnBegin()//说明此时change了所有文件了 可以上传了}, 1500)},fnBegin () {console.log('此时change了所有文件 开始上传', this.upFileList)this.submitUpload2()},// 正式上传掉后端接口submitUpload2 () {if (this.upFileList.length > 0) {this.showPercent = truethis.fileNum = new FormData()  // new formData对象this.fileNum.append('file', this.upFileList[0])  // append增加数据this.fileNum.append('name', this.upFileList[0].name)  // append增加数据let _vm = thisaxios({url: '/chc-shop/api/v1/accident/szcp/electronicfile/upload',headers: {"Content-Type": "multipart/form-data",},method: "post",data: this.fileNum,}).then(res2 => {// 每次上传当前一个后 不论成功失败就删除当前这个--如果上传失败想继续传当前这个 就把这两行注释掉this.percentNow = this.percentNow + 1this.upFileList.shift()console.log('上传返回', res2)if (res2.data.success) {// this.$message({//   message: "上传成功",//   type: 'success'// })// 进行递归 上传下一个this.submitUpload2()} else {_vm.$message({message: res2.data.return_message || '上传失败',type: "error",})// 进行递归 上传下一个this.showDesc = '上传结束,部分文件上传失败'this.submitUpload2()}}).catch(error => {console.log(error)_vm.$message({message: error || '上传失败',type: "error",})// 每次上传当前一个后 不论成功失败就删除当前这个--如果上传失败想继续传当前这个 就把这两行注释掉this.percentNow = this.percentNow + 1this.upFileList.shift()// 进行递归 上传下一个this.showDesc = '上传结束,部分文件上传失败'this.submitUpload2()})} else {this.disabledUpload = falsethis.showPercent = falsethis.upFileList = [] //清空待传列表this.$refs.upload1.clearFiles()this.fileList1 = []if ((this.percentNow == this.percentTotal) && this.percentTotal) {this.$message.success(this.showDesc ? this.showDesc : '已全部上传成功!')this.percentTotal = 0this.percentNow = 0this.showDesc = ''} else if ((this.percentNow == this.percentTotal) && this.percentTotal == 0) {this.$message.warning('请先选择文件!')this.percentTotal = 0this.percentNow = 0} else {this.$message.success('已部分上传成功,且取消后续文件上传!')this.percentTotal = 0this.percentNow = 0}return false}},// 终止后需上传submitAbort () {this.showPercent = false// .abort()不生效,故自己直接将this.upFileList置空 那么就不会走到递归了 就制止后续的上传了this.upFileList = []// this.upFileList.forEach(ele => {//   this.$refs.upload1.abort(ele)// })// this.$refs.upload1.abort()// this.$message.warning('已取消后续文件上传!')},fileErr (err, file, fileList) {this.$message({message: file.name + '上传失败',type: "error",})},// 这两个事件不会再触发--因为阻止了自动上传beforeAvatarUpload (file) {console.log('上传文件前', file)},msgSuccessOne (data, file, fileList) {console.log('成功', file)},},
};
</script>

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

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

相关文章

Controller向View传值方式总结

From: http://www.cnblogs.com/guohu/p/4377974.html 总结发现ASP.NET MVC中Controller向View传值的方式共有6种&#xff0c;分别是&#xff1a; ViewBagViewDataTempData向普通View页面传一个Model对象向强类型页面传传一个Model对象用一个ViewModel对象解决所有问题 首先我们…

记录一次bug解决过程:数据迁移

一 总结不擅长语言表达&#xff0c;勤于沟通&#xff0c;多锻炼 调试MyBatis中SQL语法:foreach 问题&#xff1b;缺少关键字VALUES。很遗憾&#xff1a;它的错误报的让人找不着北。 二 BUG描述&#xff1a;MyBatis中批量插入数据异常 <?xml version"1.0" encodin…

繁华模拟赛 ljw分雕塑

/* 用f[i][k]表示考虑到第i个雕塑&#xff0c;分成k组&#xff0c;可不可行&#xff08;这是一个bool类型的数组&#xff09; 转移&#xff1a; f[i][k]f[j][k-1],sum[i]-sum[j]合法 */ #include <cstdio> #include <cstdlib> #include <cstring> #include &…

Razor语法大全

From: http://www.cnblogs.com/dengxinglin/p/3352078.html Razor是基于framewor4以上写的一个开源项目&#xff1a;https://github.com/Antaris/RazorEngine/ Razor是包含了模板引擎和动态编译两部分。本部分就简单记录了模板引擎的一些语法&#xff0c;之后用Razor做一个代码…

el-dialog的内容不刷新;el-dialog内容有缓存;el-dialog里面的组件不刷新问题;

el-dialog里面的内容是带缓存的&#xff0c;也就是说除了第一次打开会初始化&#xff0c;其他次打开都是直接加载缓存的&#xff1b; 这就导致了有时候打开弹框时候&#xff0c;内容不刷新。有说法说是el-dialog嵌套太深大致的。 解决方法&#xff1a;直接给弹框的内容部分添加…

el-badge标记;el-tabs配合el-badge提示数字

标签选项卡配个标记数字提示 注意&#xff1a;el-tabs可以通过具名 slot 来实现选项卡的内容 <template><div><el-tabs v-model"tabValue"><el-tab-pane label"全部" name"1"></el-tab-pane><el-tab-pane lab…

[DP之计数DP]

其实说实在 我在写这篇博客的时候 才刚刚草了一道这样类型的题 之前几乎没有接触过 接触过也是平时比赛的 没有系统的做过 可以说0基础 我所理解的计数dp就是想办法去达到它要的目的 而且一定要非常劲非常快 都是一个很小的数然后有很多种接下来的方案使得这个数一下子变很大 计…

C++程序设计(第2版)课后习题答案--第11章

11.9 定义分数类Rational...... View Code 1 #include<iostream.h>2 #include<stdlib.h>3 class Rational{4 private:5 int fm,fz;6 int getZdgys(int a,int b);7 public:8 Rational(){9 fm1;fz0; 10 } 11 Rational(int a,int b); 1…

提交本地项目到github

要托管到github&#xff0c;那你就应该要有一个属于你自己的github帐号&#xff0c;所以你应该先到github.com注册 打开浏览器 在地址栏输入地址&#xff1a;github.com 填写用户名、邮箱、密码 点击Sign up即可简单地注册 2完成注册&#xff0c;进入github平台&#xff0c; 点…

php 的命名空间 看鸟哥后的随笔

我以前貌似真心没有想过php的命名空间&#xff0c;我每次写文件都会记得不让类名相重&#xff0c; 看完命名空间了这个&#xff0c;我发现可以解决我的一部分问题 1 MyLove.php2 namespace Zj;3 class Application{4 public function toMyLove(){5 echo Marx is…

vue页面截图;H5页面截图;vue项目中将特定网页内容生成图片(截图);html2canvas截图

功能&#xff1a; 1.兼容 PC 和 Mobile&#xff1b; 2.对指定的区域进行截取&#xff1b; 3.可以控制截图大小&#xff1b; 4.截图生成base64图片地址 一、安装插件 npm install html2canvas --save 或 yarn add html2canvas二、在.vue页面引入使用 import html2canvas fro…

CentOS6.8升级gcc到4.8.5总结

From&#xff1a; http://www.cjjjs.com/paper/czxt/2017222114137150.aspx [摘要] 操作系统是CentOS6.8的32位版本&#xff0c;yum自带的gcc版本为4.4.7&#xff0c;不支持C11特性。所以需要升级到4.8.5&#xff0c;至少要升级到4.8.1才完全支持C11。本文提供了自动安装脚本和…

JAVA设计模式之【单例模式】

任务管理器案例 1.单例类 package Singleton;/*** Created by Jim on 2016/9/28.*/ public class TaskManager {private static TaskManager tm null;private TaskManager() {System.out.println("创建任务管理器");}public void displayProcesses() {System.out.pr…

【云计算】K8S DaemonSet 每个node上都运行一个pod

Kubernetes容器集群中的日志系统集成实践 Kubernetes是原生的容器编排管理系统&#xff0c;对于负载均衡、服务发现、高可用、滚动升级、自动伸缩等容器云平台的功能要求有原生支持。今天我分享一下我们在Kubernetes集群中日志管理的实践方案。在这个方案中&#xff0c;除了Doc…

企业微信报错https:// open.work.weixin.qq.com/devtool/query?e=60020

企业微信报错&#xff1a; not allow to access from your ip, hint: [1667358733640290333963300], from ip: 180.164.177.83, more info at https:// open.work.weixin.qq.com/devtool/query?e60020 企业微信对60020处理&#xff1a;我是没太搞懂这个 企业微信报错60020解决…

swagger接口数据上传

后端接口参数格式&#xff1a; 1.正常大对象传参&#xff1a; 2.正常参数传参&#xff1a; 3.第三者传参&#xff1a;

值得一做》关于并查集的进化题目 BZOJ1015(BZOJ第一页计划)(normal-)

这道题和以前做过的一道经典的洪水冲桥问题很像&#xff0c;主要做法是逆向思维。&#xff08;BZOJ第10道非SB题纪念&#xff09; 先给出题目 Description 很久以前&#xff0c;在一个遥远的星系&#xff0c;一个黑暗的帝国靠着它的超级武器统治者整个星系。某一天&#xff0c;…

Functional ProgrammingLazy Code:被我忘记的迭代器

本文给出一个Functional Programming和Lazy Code的一个例子。跟着思路走&#xff0c;关键的地方会有相应的说明。 我们想实现一个判断"素数"的小程序&#xff0c;如下&#xff1a; using System;namespace FunctionalProgramming {class Program{static void Main(st…

PhpStorm配置Xdebug调试PHP程序

From: http://blog.csdn.net/ljfrocky/article/details/46531137这篇文章主要介绍了如何使用PhpStorm Xdebug调试PHP程序&#xff0c;需要的朋友可以参考下。运行环境PhpStorm版本&#xff1a;8.0.3 PHP版本&#xff1a;5.4.12 xdebug版本&#xff1a;php_xdebug-2.2.3-5.4-vc…

对刚

3 /*直接链表模拟 */ #include<cstdio> #include<iostream> #define M 100010 using namespace std; int next[M],fa[M],vis[M],n,t; int main() {//freopen("jh.in","r",stdin);//freopen("resist.in","r",stdin);//freo…