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

最近在写项目时一直使用的是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开支,用户点图片就上传了有时候会出现许多浪费的问题。
根据自己的业务需求来写其实才是最好的

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要实现Element UI的手动上传,需要使用Upload组件和对应的方法。以下是一个示例: 1. 在你的Vue组件中引入Upload组件: ```vue <template> <div> <el-upload class="upload-demo" action="/your-upload-url" :on-success="handleSuccess" :before-upload="beforeUpload" :auto-upload="false" > <el-button slot="trigger" size="small" type="primary">选取文件</el-button> <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div> </el-upload> <el-button type="primary" @click="upload">上传到服务器</el-button> </div> </template> <script> export default { methods: { handleSuccess(response, file, fileList) { // 处理上传成功的逻辑 console.log(response, file, fileList); }, beforeUpload(file) { // 验证文件格式、大小等 console.log(file); }, upload() { // 手动触发上传 this.$refs.upload.submit(); } } } </script> <style> .upload-demo { border: 1px dashed #409eff; border-radius: 6px; padding: 20px; text-align: center; color: #999; } </style> ``` 2. 在`<el-upload>`标签中,设置`action`属性为你的上传接口地址,`on-success`为上传成功时的回调函数,`before-upload`为上传之前的验证函数,`auto-upload`设为`false`表示手动触发上传。 3. 在`<el-upload>`标签中,添加一个触发上传的按钮,这里使用了`<el-button>`。 4. 在`<el-upload>`标签内部的内容为用户选择文件后展示的内容,这里使用了一个提示信息。 5. 在Vue组件的`methods`中,编写了`handleSuccess`、`beforeUpload`和`upload`三个函数。 - `handleSuccess`函数是上传成功后的回调函数,可以在其中处理上传成功后的逻辑。参数`response`为服务器返回的数据,`file`为当前上传的文件对象,`fileList`为已上传的文件列表。 - `beforeUpload`函数用于在上传之前进行文件验证,例如验证文件格式、大小等。参数`file`为当前要上传的文件对象。 - `upload`函数用于手动触发上传,通过`this.$refs.upload.submit()`来提交上传请求。 注意:以上代码中使用了Element UI的样式类名和组件,确保你已经正确引入Element UI并设置了相应的样式。 希望对你有帮助!如果还有其他问题,请继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值