实现多图片上传,formData携带动态图片,按顺序排列图片,根据序号替换图片,图片文件附带标识
-
- 需求
- 思路
- formData转化为JSON结构代码
- 单张图片上传(新增、编辑)逻辑
- 多张图片上传(有顺序要求)代码(所用到的' _' 为lodash的引用,主要用于处理数据)
需求
- 携带参数请求接口时的formData需要转化为JSON结构
- 按顺序显示的图片列表需要加上顺序标识
- 单张图片上传,单张图片携带标识参数(新增,编辑)
- 多张图片上传,多张图片携带顺序参数(新增,编辑)
- 多张图片编辑后的位置关系以及后端需要接收的标识
思路
- formData格式支持以(动态)数组形式传参,但数组中添加对象时需要对象进行转换(JSON.stringify),文件需要以一个固定的参数携带
- 图片按顺序上传时需要在携带图片的同时添加顺序标识(element ui Upload上传组件),在图片上传回调方法中对文件列表进行遍历遍历中为文件中的参数按顺序编号添加参数,值为顺序编号
- 单张图片上传
3.1 新增单张图片:只需要在文件上传时的回调方法中添加标识,请求接口前根据不同标识添加不同参数,
3.2 编辑单张图片:依据文件id对原有图片进行替换并将id赋给新图片文件携带给后端进行处理
- 多张图片上传(有顺序要求)
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.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);
}
fileData:[
{
name:'测试',
num:0
},
{
name:'测试',
num:1
},
{
name:'测试',
num:2
}
]
let formData = new FormData();
for(var i = 0;i<3;i++){
var obj = {};
obj.name = '测试';
obj.age = 18;
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
}
]
单张图片上传(新增、编辑)逻辑
<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>
handleAppTitleChange(file){
file['label']= 'appTitle';
this.appTitleUrl.url = URL.createObjectURL(file.raw);
this.handleImageChange(file,file.label);
},
handleImageChange(file, label){
if(this.editMethodUser == 1){
var fileTypeId = _.filter(this.changeFileList,['label',label])[0].fileId;
file['fileId'] = fileTypeId;
this.removeOldImageList.push(fileTypeId);
if(_.filter(this.paramsData.files,['fileId',fileTypeId]).length > 0){
this.paramsData.files.filter((v,index)=>{
if(v.fileId == fileTypeId){
this.$set(this.paramsData.files,index,file);
}
})
}else {
this.paramsData.files.push(file);
}
}else {
if(_.filter(this.paramsData.files,['label',label]).length > 0){
this.paramsData.files.filter((v,index)=>{
if(v.label == label){
this.$set(this.paramsData.files,index,file);
}
})
}else {
this.paramsData.files.push(file);
}
}
this.removeOldImageList = [... new Set(this.removeOldImageList)];
},
let formData = new FormData();
Object.entries(this.paramsData.files).forEach((file,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的引用,主要用于处理数据)
<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>
handleRemove(file, fileList) {
this.removeOldImageList.push(file.fileId);
this.deleteFileInfo.fileIdList.push(file.fileId);
this.deleteFileInfo.orderNumList.push(file.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);
v['fileId'] = this.deleteFileInfo.fileIdList[0];
this.deleteFileInfo.orderNumList.splice(0,1);
this.deleteFileInfo.fileIdList.splice(0,1);
}else {
v['orderNum'] = (index + 1);
this.deleteFileInfo.orderNumList = [];
this.deleteFileInfo.fileIdList = [];
}
}
})
this.paramsData.files = fileList;
},
let formDatas = new FormData();
var newFileList = _.sortBy(_.filter(this.paramsData.files,'raw'), function(o) { return o.orderNum; });
if(this.editMethodUser == 1){
Object.entries(newFileList).forEach((file,i) => {
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) => {
if(file[1].raw){
formDatas.append(`fileData[${i}].file`,file[1].raw);
}
});
}