首页IT科技vue实现多文件上传(Vue 批量上传,使用 el-upload 实现批量上传文件只调用一个请求,只需要一个上传按钮)

vue实现多文件上传(Vue 批量上传,使用 el-upload 实现批量上传文件只调用一个请求,只需要一个上传按钮)

时间2025-06-20 15:27:10分类IT科技浏览4461
导读:背景介绍 需求背景 后端需要批量对上传的文件进行处理 原生的 el-upload 批量上传会多次调用上传接口,不支持一次调用 前端需要对选择的文件进行批量校验...

背景介绍

需求背景 后端需要批量对上传的文件进行处理 原生的 el-upload 批量上传会多次调用上传接口               ,不支持一次调用 前端需要对选择的文件进行批量校验

2            、使用 el-upload是因为:

项目是基于饿了吗组件库开发的                   ,不想再引入其他的组件进行开发; 原生的input实现上传样式处理也比较费劲            。

在网上看了大家的实现方案      ,发现要不然就是使用 input 进行批量上传;使用 el-upload的场景都需要两个按钮【选择文件                     、上传】才能实现上面的诉求           ,考虑到这样的交互都不太友好                    ,所以使用自己的方式实现                     。

一       、实现效果

先来说说实现的效果         ,点击上传按钮       ,弹出文件选择                     ,选择后直接调用上传接口进行上传            ,只调用一个接口       。

项目效果

功能效果

请求

template代码

request代码

二         、具体说明

0. data变量说明

data() { return { uploadCfg: { fileList: [], // 默认绑定的文件列表 validFileList: [] // 通过校验的文件列表 } }; }

下面来解释下以上template中重要的两个组件属性

1. handleBeforeUpload

上传文件之前的校验:至少要包含一个excel文件;如果校验通过   ,请求接口;如果校验不通过                     ,终止接口的请求               ,并给出校验不通过的提示         。

/** * @desc 上传之前进行文件校验 * @param file 当前文件 */ handleBeforeUpload(file){ let vm = this; return new Promise((resolve, reject) => { // 收集文件列表 this.uploadCfg.validFileList.push(file); // 校验文件列表 vm.handleDebounceVarifyFile(); setTimeout(function (){ if (!_.isEmpty(vm.uploadCfg.validFileList)){ resolve(true); } else { reject(true); } }, 100); }); }

可以看到这里返回了Promise,看下官方给的解释                  ,如下图                  ,就是说支持用 Promise的方式返回结果   ,没有直接返回 false的原因下面说明一下                    。

el-upload的handleBeforeUpload会在批量上传的时候触发多次               ,即选择几个文件就会调用几次                   ,我们的需求是      ,至少要包含一个excel文件           ,这种情况下需要收集所有选中的文件进行批量校验                    ,单个的触发是不能满足的         ,所以这里使用了一个【防抖函数】handleDebounceVarifyFile通过短时间内最后一次触发       ,来达到批量校验文件的效果           。

因为会多次触发                     ,所以这里的校验函数            ,返回的是一个Promise      。

下面是防抖函数的逻辑说明   ,具体可以根据自己的应用场景去开发这里的逻辑

/** * @desc 防抖触发文件上传前                     ,保证批量校验 */ handleDebounceVarifyFile: _.debounce(function (){ let excel_file = {}; if (_.isEmpty(this.uploadCfg.validFileList)){ return; } excel_file = this.uploadCfg.validFileList.find(item => { return /\.(xls)|\.(xlsx)$/.test(item.name); }); // 如果文件校验不合理               ,清空合法文件列表,并提示 if (_.isEmpty(excel_file)){ this.uploadCfg.validFileList = []; this.$message.warning(至少上传一个xls或者xlsx格式的文件!); } }, 20)

2. handleUploadHttp

这里使用自定义的上传方法                  ,和上传前校验一样                  , el-ipload默认会多次调用上传接口   ,我们需要做的也是使用防抖的思路               ,控制最后一次触发上传回调的时候去构造批量的文件数据                   ,请求接口      ,下面是具体代码:

/** * @desc 自定义上传 */ handleUploadHttp(){ this.handleDebounceUpload(); } /** * @desc 防抖触发文件上传前           ,保证批量上传 */ handleDebounceUpload: _.debounce(function (){ if (_.isEmpty(this.uploadCfg.validFileList)){ return; } let formData = new FormData(); this.uploadCfg.validFileList.forEach((item_file) =>{ formData.append(`files`,item_file); }); batchUploadApi.uploadXsxx(formData).then(()=> { this.$message.success(附件已上传成功                    ,请等待数据入库!); this.uploadCfg.validFileList = []; }).catch(err => { console.log(批量上传附件失败, err); }); }, 20)

三                    、结语

至此         ,个人认为比较完美的解决了问题       ,分享出来希望可以帮助到有同样问题的人~

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
pandas中的数据结构(03-Pandas详解)