长春市长春网站建设,网站建设需要怎样的经营范围,服装网页设计欣赏,短网址网站建设场景#xff1a; 需求是接口一次上传一个文件#xff0c;前一个文件上传成功后再调下一个接口上传下一个文件。 el-upload本身就支持多文件上传。但是它是并发进行#xff0c;例如#xff1a;选择一千个文件后#xff0c;是一千个文件自动立马并行调用一千个后端接口去上传… 场景 需求是接口一次上传一个文件前一个文件上传成功后再调下一个接口上传下一个文件。 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 stylemargin-left: 10px; sizesmall typesuccess clicksubmitUpload2手动点击上传/el-button -- 以下代码可直接复制使用注意将axios的接口上传地址改成自己的
templatediv classgroup_insurance_order1 stylepadding-top:100px;!--:auto-uploadfalse 是否在选取文件后立即进行上传 false阻止自动上传 -- 且上传前和上传成功的事件都不会再触发 只会触发change事件了:http-requestuploadFile 覆盖默认的上传行为可以自定义上传的实现this.$refs.upload1.submit() 会触发调用uploadFile函数--el-upload refupload1 classupload-demo action/chc-shop/api/v1/accident/szcp/electronicfile/upload accept.pdf :disableddisabledUpload :auto-uploadfalse :on-changechangeFile :on-errorfileErr :on-exceedhandleExceed :file-listfileList1 :before-uploadbeforeAvatarUpload :on-successmsgSuccessOne :datafileData list-typepicture drag :show-file-listfalse :multipletrue :limit1000i classel-icon-upload/idiv classel-upload__text stylemargin-top: -10px;line-height: 20px;将文件拖到此处em v-if!disabledUpload或点击上传(单个文件需小于100M,一次最多上传1000个pdf文件)/emem v-else文件正在上传中请等待.../em/div/el-uploaddiv!-- el-button stylemargin-left: 10px; sizesmall typesuccess clicksubmitUpload2手动点击上传/el-button --el-button v-ifshowPercent stylemargin-left: 10px; sizesmall typesuccess clicksubmitAbort取消后续文件上传/el-button/divdiv stylecolor:orange; v-ifshowPercent上传过程请勿刷新浏览器和跳转其他页面.../div!-- 进度条 --el-progress v-ifshowPercent :percentageNumber((percentNow*100/percentTotal).toFixed(0))/el-progress/div
/templatescript
import axios from axios
export default {data () {return {fileNum: , // 单词递归上传的文件upFileList: ,//需要依次上传的待传列表percentTotal: 0,//总上传个数percentNow: 0,//当前上传个数showDesc: ,//结束文案showPercent: false,//显示上传进度条time: null,// change事件是否结束 是否可以直接调手动上传事件目前设置1.5sdisabledUpload: 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