关于ElementUi的Upload组件手动提交问题及代码优化

本文详细介绍了在Vue项目中使用ElementUI的Upload组件进行图片上传时遇到的问题及解决方案,包括图片类型检查、文件大小限制、手动上传与拦截、避免OSS开支浪费。通过监听on-change事件来移除非图片文件,手动调用submit方法上传文件,并通过axios异步提交文件,确保图片上传完成后再提交其他表单数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在写项目时一直使用的是Elementui的Upload组件
在这里插入图片描述
照片墙的确很好用,不过会引发一些问题。
比如:
在这里插入图片描述
图片类型不对,fileList里是没有第二个文件的。但是照片墙已经显示了,我暂时将其视作bug吧。
解决办法:
upload有beforeUpload属性 可是该属性在我实验过后发现
只能适用于单个文件,多文件的照片墙可以正常拦截,不过
照片墙会出现显示BUG。并且为了节省OSS的开支,选择手动
上传。使用onchange的属性监控添加文件的type是否为图片
不是图片直接fileList.pop()移除,以免显示BUG。
代码:

<el-upload
 action="/file/imgListUpload"
list-type="picture-card"
:limit="5"
ref="proof"
:before-upload="beforeUpload"
:auto-upload="false"
:on-change="changeFile"
:on-remove="handleRemove">
<i class="el-icon-plus" style="line-height:148px"></i>
</el-upload>
//手动上传的拦截 由于使用了手动上传 on-success不可用
            changeFile(file, fileList){
                const isJPG = file.raw.type === "image/jpeg" || "image/png" || "image/jpg"
                const isLt2M = file.size / 1024 / 1024 < 5

                //isJPG之所以不用!的方式是因为如果不符合上面的表达式会返回其他数据,!无法判断是否true
                if (isJPG!=true) {
                    this.$message.error("上传图片只能是 JPG,JPEG,PNG 格式!")
                    fileList.pop();
                }
                if (!isLt2M) {
                    this.$message.error("上传图片大小不能超过 5MB!")
                    fileList.pop();
                }
            }

拦截类型不对的文件主要是upload的on-change的方法
监听每一次添加图片,这样如果添加了不对的图片直接将其从fileList里面清掉就不会出现显示BUG了
我这边是手动上传 所以使用了on-change
如果获取文件直接上传的话(auto-upload=true)就可以这样

//立即上传的拦截方案 根据上传成功以后返回的code 文件类型在后台判断
            proofImgSuccess(res, file,fileList){
                if(res.code === 200){
                    this.goodsErrorImgs.push(res.data);
                }
                else{
                    fileList.pop();
                }
            }

最后就是手动上传
upload的auto-upload关闭以后可以用

this.$refs.proof.submit()

进行手动上传。不过手动上传会加大方法的压力,如果使用OSS的并且在每次
上传后关闭连接的话建议synchronized锁住方法,以防线程
拿到连接以后被其他线程关闭,抛出500。
而且还有一个问题。如果要提交包括文件在内的其他表单内容的话,会拿不到返回的图片数据。例如response之类的。因为异步执行,执行submit以后会自动执行后面代码,假如打了console.log的话 console.log出来的有时候比submit还快…
而且console.log直接打印fileList的时候是会显示出response的属性,可是用Object.keys获取所有属性时却不存在response,很简单就是因为运行submit时console在submit没有执行完就执行了。说的有点多,也不知道解释清楚没。

我最终的选择是不用submit,拿到文件列表自己手动上传。submit不用,http-request覆盖也不用。就用this.$refs.proof.uploadFiles拿到待上传的文件。然后自己跑文件上传接口,用await修饰提交方法就可以让图片提交完毕以后再提交其他数据。
这是手动提交图片

async submitImgs(upLoadFiles){
                var target = [];
                for (var i=0; i<upLoadFiles.length;i++) {
                    let fileObj = upLoadFiles[i].raw;
                    let fd = new FormData();
                    fd.append("file",fileObj);
                    let config = {headers:{'Content-Type': 'multipart/form-data'}}
                    await axios.post("/file/imgListUpload",fd,config).then(res=>{
                        if(res.data.code == 200){
                            target.push(res.data.data);
                        }
                    })
                }
                target.forEach(item=>{
                    this.formLabelAlign.imgs = this.formLabelAlign.imgs+item+","
                })
                this.formLabelAlign.imgs = this.formLabelAlign.imgs.substring(0, this.formLabelAlign.imgs.lastIndexOf(','));
                return true;
            }

我后台存储的图片集URL由逗号分割,直接删除最后一个逗号以免切割出一个空值
文件上传要注意Content-type为multipart/form-data
upload的uploadFiles的raw就是一个文件
最后提交其他数据

async certification(formLabelAlign){
                this.errorLoading = true;
                await this.submitImgs(this.$refs.proof.uploadFiles)

                this.$refs.formLabelAlign.validate((valid)=>{
                        if (valid) {
                            post("/goods/submitGoodsError",this.formLabelAlign).then(res=>{
                                //提交
                            })
                        }
                        else{
                            this.$message.error("请正确填写");
                        }
                })
            }

我这样写主要是节省OSS开支,用户点图片就上传了有时候会出现许多浪费的问题。
根据自己的业务需求来写其实才是最好的

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值