首页 > 其他分享 >el-upload删除已选图片存在问题

el-upload删除已选图片存在问题

时间:2022-12-01 17:38:57浏览次数:33  
标签:el res OSS upload param file 上传 已选 图片

前言

昨天写了JAVA整合阿里云OSS/VUE上传阿里云OSS
这篇文章,上传是没有问题了,但是在删除的时候有点问题,如果在只上传单张图片的场景下,el-upload是很方便搞定的,但是如果是多张图片,上传是没问题,但是如果上传后的图片要做删除操作还是有点恶心的,本文主要针对VUE端,废话先不多说,场景引入一下!

场景引入

代码如下

<template>
    <div>
     <el-upload
                :limit="4"
                accept=".png,.jpg"
                list-type="picture-card"
                :on-exceed="handleExceed"
                :on-preview="handlePictureCardPreview"
                :on-remove="handleRemove"
                :http-request="fileUpload"
                action="#"
                multiple>
            <i class="el-icon-plus"></i>
        </el-upload>
    </div>
</template>

<script>
    export default {
        name: "imgUpload",
        data(){
            return{
            	haveUploadImg:[],//成功上传OSS图片数据
                dialogImageUrl: '',
                dialogVisible: false,
            }
        },
        methods:{
			 //OSS图片上传相关

			//删除el-upload上显示图片
            handleRemove (file, fileList) {
                console.log(file, fileList);
            },

            //图片预览
            handlePictureCardPreview (file) {
                this.dialogImageUrl = file.url;
                this.dialogVisible = true
            },

            //图片上传
            fileUpload(param){
                var _this=this;
                this.$CommonUtil.fileUploadOss(param.file,500000,res=>{
                    _this.haveUploadImg.push(res);//将上传OSS的图片添加到haveUploadImg中
                    console.log("上传阿里云OSS后得到的访地址===>",res);
                });
            },
            
            //超过图片上传限制
            handleExceed (files, fileList) {
                this.$message.warning(`当前限制选择 4 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`)
            },
		}
    }
</script>

OSS图片上传工具

let axios = require('axios')
import {getOssSignature} from "../server/common"
import {Notification} from "element-ui";
import SparkMD5 from "spark-md5";//MD5工具 npm install spark-md5 --save
const commonUtils={


 /**
     * 格式化文件大小
     * @param size
     * @returns {string}
     */
    formFileSize(originalSize){
        var size = "";
        if( originalSize < 0.1 * 1024 ){ //如果小于0.1KB转化成B
            size = originalSize.toFixed(2) + "B";
        }else if(originalSize < 0.1 * 1024 * 1024 ){//如果小于0.1MB转化成KB
            size = (originalSize / 1024).toFixed(2) + "KB";
        }else if(originalSize < 0.1 * 1024 * 1024 * 1024){ //如果小于0.1GB转化成MB
            size = (originalSize / (1024 * 1024)).toFixed(2) + "MB";
        }else{ //其他转化成GB
            size = (originalSize / (1024 * 1024 * 1024)).toFixed(2) + "GB";
        }

        var sizestr = size + "";
        var len = sizestr.indexOf("\.");
        var dec = sizestr.substr(len + 1, 2);
        if(dec == "00"){//当小数点后为00时 去掉小数部分
            return sizestr.substring(0,len) + sizestr.substr(len + 3,2);
        }
        return sizestr;
    },

    /**
     * 文件MD5码
     * @param file
     * @param resFileMD5Name 返回方法(返回MD5文件名.xxx)
     */
    fileMD5(file,resFileMD5Name){
        let fileReader = new FileReader();
        let spark = new SparkMD5.ArrayBuffer();
        // 获取文件二进制数据
        fileReader.readAsArrayBuffer(file);
        fileReader.onload = function (e) {
            spark.append(e.target.result);
            resFileMD5Name(spark.end());
        };
    },

    /**
     * MD5.xxx
     * @param file
     * @param resFileMD5Name 返回方法(返回MD5文件名.xxx)
     */
    fileMD5Suffix(file,resFileMD5Name){
        let fileReader = new FileReader();
        let spark = new SparkMD5.ArrayBuffer();

        // 获取文件二进制数据
        fileReader.readAsArrayBuffer(file);
        fileReader.onload = function (e) {
            let fileName=file.name.toString();
            spark.append(e.target.result);
            //console.log("fileName===>",fileName.substring(fileName.lastIndexOf(".")));
            resFileMD5Name(spark.end()+fileName.substring(fileName.lastIndexOf(".")));
        };
    },

    /**
     * OSS上传工具
     * @param file 文件
     * @param maxSize 最大size
     * @param resfun 回调方法(回调数据用的)
     */
    fileUploadOss(file,maxSize,resfun){
        let fileSize=file.size;//文件大小
        let fileMD5Name;//MD5文件码
        let fileName=file.name;//原始文件
        //console.log("file===>",file);
        //console.log("fileSize===>",fileSize);

        //文件大小校验
        if (fileSize>maxSize){
            Notification({
                title: '文件上传异常',
                message: "超过最大上传大小",
                type: 'info'
            });
            console.error("超过最大上传大小");
            return;
        }

        //获取文件MD5码
        this.fileMD5Suffix(file,resFileMD5Name=>{
            //console.log("resFileMD5Name===>",resFileMD5Name);
            fileMD5Name = resFileMD5Name;
        });

        //获取签名
        getOssSignature().then(res =>{
            //console.log("signature===>",res);
            let sendData = new FormData();
            sendData.append('OSSAccessKeyId', res.accessid);
            sendData.append('policy', res.policy);
            sendData.append('Signature', res.signature);
            sendData.append('keys', res.dir);
            sendData.append('key', res.dir + fileMD5Name);
            sendData.append('success_action_status', 200); // 指定返回的状态码
            sendData.append('file', file);
            axios.post(res.host, sendData).then(res => {
                //console.log("阿里云OSS上传成功===>",res);
                //console.log("fileMD5Name===>",fileMD5Name);

                //得到上传后完整访问路径
                let fullImgUrl=Config.imgUrl + fileMD5Name;
                //console.log('得到上传到阿里云的图片地址===>' + fullImgUrl)

                //格式化文件size
                let formFileSize = this.formFileSize(fileSize);

                //返回上传数据对象
                resfun({
                    url:fullImgUrl,//图片全路径
                    name:fileName,//原始文件名
                    imgDirUrl:res.dir + fileMD5Name,//加文件夹地址
                    size:formFileSize,//格式化后文件大小
                });
            })
        }).catch(err =>{
            console.error("获取阿里云签名失败")
        });

    }
}

export default commonUtils;

问题描述
我们如果在el-upload同时选中多张图片上传,那么就会调用多次fileUpload,这个没问题,fileUpload中OSS上传成功后我们将上传OSS的图片数据保存到haveUploadImg中,也就是这行代码

			//图片上传
            fileUpload(param){
                console.log("param.file.uid===>",param.file.uid);
                this.$CommonUtil.fileUploadOss(param.file,500000,res=>{
                    this.haveUploadImg.push(res);//将上传OSS的图片添加到haveUploadImg中
                    console.log("上传阿里云OSS后得到的访地址===>",res);
                });
            },

但是我们点击以上传图片上的删除按钮时
el-upload删除已选图片存在问题_上传
el-upload会调用handleRemove方法,那么这个在el-upload其实是已经将这张图片删除掉的,这里handleRemove方法其实是已经删除后的回调,那么我们这里虽然el-upload组件上显示的图片已经删除了,但是我们实际保存上传OSS图片的haveUploadImg中对应的图片还是没删除!

handleRemove方法
handleRemove方法有两个参数file和fileList,file代表的是当前删除的项,fileList代表的是删除后剩余的项,那么我们在这个方法中其实是无法通过file和fileList得到用户删除的到底是那张照片的,这里我刚开始想的是通过比对照片名称来删除,但是这个感觉不靠谱,虽然我们能在file得到文件名

解决

铺垫
查阅了一下资料后发现el-upload其实给每张上传的图片都会定一个uid,然后我们在handleRemove方法的file参数中也能拿到当前删除的图片的uid,那么我们改造下代码

代码改造
改造OSS上传工具代码,我们将每张上传OSS照片的uid也返回出去

				//返回上传数据对象
                resfun({
                    url:fullImgUrl,//图片全路径
                    name:fileName,//原始文件名
                    imgDirUrl:res.dir + fileMD5Name,//加文件夹地址
                    size:formFileSize,//格式化后文件大小
                    uid:file.uid//当前图片标识id  el-upload提供
                });

图片上传代码不变,那么此时我们res返回的数据中就多了图片的uid标识

			//图片上传
            fileUpload(param){
                console.log("param.file.uid===>",param.file.uid);
                this.$CommonUtil.fileUploadOss(param.file,500000,res=>{
                    this.haveUploadImg.push(res);//将上传OSS的图片添加到haveUploadImg中
                    console.log("上传阿里云OSS后得到的访地址===>",res);
                });
            },

改造handleRemove移除图片方法,也就是当我们点击el-upload上显示的图片的删除按钮时这里改造后代码就会通过当前删除图片的uid和haveUploadImg数组对象中的uid进行对比,然后得到下标,从而删除数据!

			//移除图片 (移除el-upload上显示的图片+移除已上传的图片)
            handleRemove (file) {//执行该方法时自动移除el-upload上显示的图片,所以方法体内只需要移除已上传的图片即可
                console.log("el-upload上显示的图片移除的file.uid==>"+file.uid);
                const index =this.haveUploadImg.findIndex(item => item.uid === file.uid)
                this.haveUploadImg.splice(index, 1)//移除已上传的图片
            },

标签:el,res,OSS,upload,param,file,上传,已选,图片
From: https://blog.51cto.com/u_15899048/5903390

相关文章

  • MySQL删除数据的三种方式:delete、drop、truncate的区别
    本篇主要讨论MySQL删除数据的三种方式:delete、drop、truncate的区别当行数据批量delete时,InnoDB如何处理自增ID的目录参考来源:1、建表2、插入数据3、删除数据deletetru......
  • ElasticSearch面试题
    1.为什么要使用ElasticSearch系统中的数据,随着业务的发展,时间的推移,将会非常多,而业务中往往采用模糊查询进行数据的搜索,而模糊查询会导致查询引擎放弃索引,导致系统......
  • Linux搭建ElasticSearch集群
    前言这是整个ElasticSearch搭建的最后一篇文章,其实对我而言ElasticSearch在Linux上搭建集群写这篇文章意义并不大,只是为了补充这个空白而已,所以这篇文章并不会讲解很详细......
  • ElasticSearch集群数据读写流程
    前言本章作为ElasticSearch分布式集群的附属章节,主要讲解ElasticSearch集群环境下数据是如何读写的,既然讲到读写,那么ElasticSearch的更新就是基于二者的结合,顺带也讲一下......
  • ELasticSearch优化
    硬件优化Elasticsearch的基础是Lucene,所有的素引和文档数据是存储在本地的磁盘中,具体的路径可在ES的配置文件./config/elasticsearch.yml中配置,如下:磁盘在现代服务......
  • ElasticSearch分布式集群
    前言关于ElasticSearch集群概念这里就不多废话了,详细可见ElasticSearch基本介绍、ElasticSearch集群系统架构单节点集群我们可以创建一个索引,为这个索引创建三个分片......
  • SpringBoot整合ElasticSearch-SpringData
    前言之前写过一篇SpringBoot整合ElasticSearch是使用的elasticsearch-rest-high-level-client,这篇文章使用Spring-Data来操作ElasticSearch。关于ElasticSearch的搭建我......
  • ElasticSearch集群概念
    单机存在的问题单台Elasticsearch服务器提供服务,往往都有最大的负载能力,超过这个阈值,服务器性能就会大大降低甚至不可用,所以生产环境中,一般都是运行在指定服务器集......
  • Windows安装ElasticSearch
    前言习惯使用docker安装各种中间件了,但是程序包安装方式也不能丢呀。官网下载地址,我这里使用的是7.4.2,如果需要使用其他版本,更改连接后面的版本号即可!下载下载速度还......
  • ElasticSearch集群系统架构
    前言全面几篇文章主要是使用单机跑ElasticSearch的,在生产环境为了保证高可用和高吞吐量我们都会采用集群的方式部署。那么本章不涉及ElasticSearch集群的搭建,只涉及理论......