element ui Upload 上传组件 实现多图片上传,formData携带动态图片,formData实现JSON结构,按顺序排列图片,根据序号替换图片,图片文件附带标识

实现多图片上传,formData携带动态图片,按顺序排列图片,根据序号替换图片,图片文件附带标识

    • 需求
    • 思路
    • formData转化为JSON结构代码
    • 单张图片上传(新增、编辑)逻辑
    • 多张图片上传(有顺序要求)代码(所用到的' _' 为lodash的引用,主要用于处理数据)

需求

  1. 携带参数请求接口时的formData需要转化为JSON结构
  2. 按顺序显示的图片列表需要加上顺序标识
  3. 单张图片上传,单张图片携带标识参数(新增,编辑)
  4. 多张图片上传,多张图片携带顺序参数(新增,编辑)
  5. 多张图片编辑后的位置关系以及后端需要接收的标识

思路

  1. formData格式支持以(动态)数组形式传参,但数组中添加对象时需要对象进行转换(JSON.stringify),文件需要以一个固定的参数携带
  2. 图片按顺序上传时需要在携带图片的同时添加顺序标识(element ui Upload上传组件),在图片上传回调方法中对文件列表进行遍历遍历中为文件中的参数按顺序编号添加参数,值为顺序编号
  3. 单张图片上传
    3.1 新增单张图片:只需要在文件上传时的回调方法中添加标识,请求接口前根据不同标识添加不同参数,
    3.2 编辑单张图片:依据文件id对原有图片进行替换并将id赋给新图片文件携带给后端进行处理
  4. 多张图片上传(有顺序要求)
    4.1 多张图片上传时需要给每一张一个固定顺序(从一开始上传时顺序就固定后续修改也是对应这一顺序)
    4.2 一开始固定位置后,删除文件后,再上传文件这时候上传的文件就会随删除的文件的顺序进行递进赋值(例如:删除了1位置,那么上传时就赋予1位置顺序;删除1,2位置那么上传时递进先赋予1位置顺序再赋予2位置顺序…按删除顺序递进)
    4.3 formData携带参数时需要考虑以下情况:
    4.3.1 需要对新旧文件进行判断
    4.3.2 只添加新文件
    4.3.3 需要对新文件列表进行排序(正常的列表顺序结构[0],[1]…)
  5. 多张图片编辑后的位置关系以及后端需要接收的标识
    5.1 位置为上传图片时的固定位置(上传后)
    5.2 后端以固定位置变更文件信息

formData转化为JSON结构代码

let formData = new FormData();
for(var i = 0;i<3;i++){
	formData.append(`fileData[${i}].name`,'测试');
	formData.append(`fileData[${i}].num`,i);
}
//后端(JAVA)使用List接收
//接收数据效果:
fileData:[
	{
		name:'测试',
		num:0
	},
	{
		name:'测试',
		num:1
	},
	{
		name:'测试',
		num:2
	}
]
//forData携带参数为对象时需要进行转换(携带请求接口)
let formData = new FormData();
for(var i = 0;i<3;i++){
	var obj = {};
	obj.name = '测试';
	obj.age = 18;
	//formData.append(`fileObj[${i}].obj`,JSON.stringify(obj)); //请求接口时需要对其进行JSON.stringify转换,否则会被formData转化为[object,object]
	formData.append(`fileObj[${i}].obj`,obj);
	formData.append(`fileObj[${i}].num`,i);
}
//接收数据效果:
fileObj:[
	{
		obj:{
			name:'测试',
			age:18
		},
		num:0
	},
	{
		obj:{
			name:'测试',
			age:18
		},
		num:1
	},
	{
		obj:{
			name:'测试',
			age:18
		},
		num:2
	}
]
//后端接收转换为JSON即可

单张图片上传(新增、编辑)逻辑

//html
<el-upload
    action=""
    :on-change="handleAppTitleChange"
    :auto-upload="false"
    :show-file-list="false"
    class="uploadImage"
    ref="uploadImage">
    <img v-if="appTitleUrl.url" :src="appTitleUrl.url" class="uploadImage-avatar">
    <i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
//js
//上传App Title图片时(单个图片)
handleAppTitleChange(file){
    file['label']= 'appTitle';
    this.appTitleUrl.url = URL.createObjectURL(file.raw);
    this.handleImageChange(file,file.label);
},

//上传图片后对已存在的文件进行处理
handleImageChange(file, label){

  if(this.editMethodUser == 1){ //为编辑状态 对已经存在的App图片进行替换处理
    var fileTypeId = _.filter(this.changeFileList,['label',label])[0].fileId; //取出改变后的file
    file['fileId'] = fileTypeId; //重新设置id
    this.removeOldImageList.push(fileTypeId); //添加已改变的文件的id

    if(_.filter(this.paramsData.files,['fileId',fileTypeId]).length > 0){ //判断fileTypeId是否已存在
      this.paramsData.files.filter((v,index)=>{
        if(v.fileId == fileTypeId){ //是否已存在当前fileTypeId的文件
          this.$set(this.paramsData.files,index,file); //存在则进行替换
        }
      })
    }else {
      this.paramsData.files.push(file); //fileTypeId不存在时,添加到数组
    }

  }else { //对未存在的App图片进行添加
    if(_.filter(this.paramsData.files,['label',label]).length > 0){ //判断label是否已存在
      this.paramsData.files.filter((v,index)=>{
        if(v.label == label){ //是否已存在当前fileTypeId的文件
          this.$set(this.paramsData.files,index,file); //存在则进行替换
        }
      })
    }else {
      this.paramsData.files.push(file); //fileTypeId不存在时,添加到数组
    }
  }

  this.removeOldImageList = [... new Set(this.removeOldImageList)];//对已修改的文件Id列表进行去重     
},

//formData
let formData = new FormData(); //以FormData形式带参
            
Object.entries(this.paramsData.files).forEach((file,i) => { //将图片文件参数转为fileList: (binary)格式
    //fileData[${i}]对应一个单独对象
    if(file[1].raw){
        if(file[1].label == 'appLogo'){
            file[1].fileDesc = new Object();
            file[1].fileDesc['title'] = this.paramsData.platform;
            file[1].fileDesc['label'] = file[1].label;
            formData.append(`fileData[${i}].fileDesc`,JSON.stringify(file[1].fileDesc));
        }else if(file[1].label == 'appImage'){
            file[1].fileDesc = new Object();
            file[1].fileDesc['label'] = file[1].label;
            formData.append(`fileData[${i}].fileDesc`,JSON.stringify(file[1].fileDesc));
        }else if(file[1].label == 'appTitle'){
            file[1].fileDesc = new Object();
            file[1].fileDesc['title'] = this.paramsData.title;
            file[1].fileDesc['label'] = file[1].label;
            formData.append(`fileData[${i}].fileDesc`,JSON.stringify(file[1].fileDesc));
        }
        formData.append(`fileData[${i}].file`,file[1].raw);
    }
});

多张图片上传(有顺序要求)代码(所用到的’ _’ 为lodash的引用,主要用于处理数据)

//html
<el-form-item prop="imageList">
    <el-upload
        action=""
        :multiple="true"
        list-type="picture-card"
        :on-change="handleImageChange"
        :on-preview="handlePictureCardPreview"
        :on-remove="handleRemove"
        :auto-upload="false"
        :file-list="paramsData.files"
        class="uploadImage"
        ref="uploadImage">
        <div class="uploadIcon">
            <i class="el-icon-plus"></i>
            <span>上传</span>
        </div>
    </el-upload>
    <el-dialog :visible.sync="dialogVisible" :modal-append-to-body="false">
        <img width="100%" :src="dialogImageUrl" alt="">
    </el-dialog>
</el-form-item>
//js
//清除已有图片
handleRemove(file, fileList) {
    this.removeOldImageList.push(file.fileId); //添加清除图片的fileId
    this.deleteFileInfo.fileIdList.push(file.fileId); //添加清除图片的fileId
    this.deleteFileInfo.orderNumList.push(file.orderNum); //添加清除图片的orderNum
    this.paramsData.files = fileList;  //重新设置回显
},
//上传图片时
handleImageChange(file, fileList){
    fileList.filter((v,index)=>{
      if(v.raw && !v.orderNum){
        if(this.deleteFileInfo.orderNumList.length > 0){
          v['orderNum'] = (this.deleteFileInfo.orderNumList[0] + 1); //给新上传的文件添加orderNum
          v['fileId'] = this.deleteFileInfo.fileIdList[0]; //给新上传的文件添加fileId
          this.deleteFileInfo.orderNumList.splice(0,1); //赋值一个就删除一个
          this.deleteFileInfo.fileIdList.splice(0,1); //赋值一个就删除一个
        }else {
          v['orderNum'] = (index + 1); //+1是为了避免orderNum为0的情况(!0为true)
          this.deleteFileInfo.orderNumList = []; //已经将所有orderNum重新添加到文件列表中需要清除为空数组
          this.deleteFileInfo.fileIdList = []; //已经将所有fileIdList重新添加到文件列表中需要清除为空数组
        }
      }
    })
	this.paramsData.files = fileList;
},

//formData
let formDatas = new FormData(); //以FormData形式带参
var newFileList = _.sortBy(_.filter(this.paramsData.files,'raw'), function(o) { return o.orderNum; }); //取出新上传的文件并按orderNum进行排序
if(this.editMethodUser == 1){ //为编辑状态
   Object.entries(newFileList).forEach((file,i) => { //将图片文件参数转为fileList: (binary)格式
    formDatas.append(`fileData[${i}].file`,file[1].raw);
    formDatas.append(`fileData[${i}].orderNum`,(file[1].orderNum - 1));
  });
}else {
  Object.entries(this.paramsData.files).forEach((file,i) => { //将图片文件参数转为fileList: (binary)格式
      if(file[1].raw){
        formDatas.append(`fileData[${i}].file`,file[1].raw);
      }
  });
}




你可能感兴趣的:(formdata,element,ui,formdata实现JSON)