需求:el-upload照片墙自定义上传多张图片(手动一次性上传多张图片)包含图片回显,删除,预览,在网上看了很多,都没有说怎么把数据转为file格式的,找了很久最终实现,
难点:怎么把接口获取到的图片转为file格式,如果不是file格式的话,那么后端无法识别,并且还要携带额外的参数
1.调用接口获取已上传图片,格式如下
获取到数据后,进行回显(调用接口我就不写了,我只写数据获取到后转为file格式)
fileImgList:用于照片回显
process.env.VUE_APP_SERVE:这个是全局的,公司地址,比如https://xx.cn,如果图片显示不出来,可以问后端要不要拼接其他,可以在浏览器测试
以下这俩个方法,直接复制,把参数对好就能转为file,格式是[FILE]
imageToBase64:图片转base64
base64ToFile:base64转File
that.formInline.files:用于存储file格式图片
javascript
query() {
if (files.length > 0) {
files.forEach((item) => {
this.fileImgList.push({
url: process.env.VUE_APP_SERVE + '/files' + item.path,
name: item.originalname
});
var image = new Image();
image.crossOrigin = '';
image.src = process.env.VUE_APP_SERVE + '/files' + item.path; // 'https://xx.cn' + item
const that = this;
image.onload = function () {
const base64 = that.imageToBase64(image); // 图片转base64
const file = that.base64ToFile(base64, item.path); // base64转File
that.formInline.files.push(file);
};
});
}
},
imageToBase64(img) {
var canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, img.width, img.height);
var ext = img.src.substring(img.src.lastIndexOf('.') + 1).toLowerCase();
var dataURL = canvas.toDataURL('image/jpeg' + ext);
return dataURL;
},
base64ToFile(urlData, fileName) {
const arr = urlData.split(',');
const mime = arr[0].match(/:(.*?);/)[1];
const bytes = atob(arr[1]); // 解码base64
let n = bytes.length;
const ia = new Uint8Array(n);
while (n--) {
ia[n] = bytes.charCodeAt(n);
}
return new File([ia], fileName, { type: mime });
}
2.删除已上传图片
直接复制,这个是删除[FILE,FILE]的图片
javascript
handleRemove(file) {
// 从列表中删除当前的图片
var that = this;
try {
var delname = file.url.split('/');
that.formInline.files = that.formInline.files.filter((ele) => {
var name = ele.name.split('/');
return name[name.length - 1] !== delname[delname.length - 1];
});
console.log(that.formInline.files);
} catch (error) {}
}
3.上传图片
上传图片的change事件,每次上传成功把file.raw给files,注意!!file.raw就是后端需要的file格式的图片
javascript
OnChange(file, fileList) {
const isType = file.type === "image/jpeg" || "image/png";
const isLt5M = file.size / 1024 / 1024 < 5;
if (!isType) {
this.$message.error("上传图片只能是 JPG 格式!");
fileList.pop();
}
if (!isLt5M) {
this.$message.error("上传图片大小不能超过 5MB!");
fileList.pop();
}
this.formInline.files.push(file.raw);
},
4.上传多张图片并且携带额外参数
注意!!这边如果要传数组,需要先转换为json格式再发给后端
javascript
async setCompanySubmit() {
let formData = new FormData(); // 用FormData存放上传文件
this.formInline.files.forEach((file, index) => {
formData.append('files', file);
});
let { name, tel, truename, id } = this.formInline;
formData.append('name', name);
formData.append('tel', tel);
formData.append('truename', truename);
formData.append('id', id);
const res = await Api_setCompany(formData);
if (res.code == 200) {
this.$message.success('成功!!!');
this.unitDialogVisible = false;
this.fileImgList = [];
this.$refs.uploadCompanyRef.clearFiles();
}
}
上传参数如下,有多个files文件
5.完整代码(仅作参考,需要根据实际情况修改)
javascript
<template>
<div>
<el-upload
action="#"
list-type="picture-card"
multiple
:on-remove="handleRemove"
:on-change="OnChange"
:file-list="fileImgList"
:auto-upload="false"
ref="uploadCompanyRef"
>
<i class="el-icon-plus"></i>
<div class="el-upload__tip" slot="tip">只能上传jpg/png文件,最多上传5张且单张图片不超过5M</div>
</el-upload>
<el-button type="primary" size="default" @click="setCompanySubmit()">上传</el-button>
</div>
</template>
<script>
export default {
data() {
return {
fileImgList: [],
formInline: {
files: [],
name: '',
id: 0
}
};
},
mounted() {
this.query();
},
methods: {
query() {
if (files.length > 0) {
files.forEach((item) => {
this.fileImgList.push({
url: process.env.VUE_APP_SERVE + '/files' + item.path,
name: item.originalname
});
var image = new Image();
image.crossOrigin = '';
image.src = process.env.VUE_APP_SERVE + '/files' + item.path; // 'https://xx.cn' + item
const that = this;
image.onload = function () {
const base64 = that.imageToBase64(image); // 图片转base64
const file = that.base64ToFile(base64, item.path); // base64转File
that.formInline.files.push(file);
};
});
}
},
imageToBase64(img) {
var canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, img.width, img.height);
var ext = img.src.substring(img.src.lastIndexOf('.') + 1).toLowerCase();
var dataURL = canvas.toDataURL('image/jpeg' + ext);
return dataURL;
},
base64ToFile(urlData, fileName) {
const arr = urlData.split(',');
const mime = arr[0].match(/:(.*?);/)[1];
const bytes = atob(arr[1]); // 解码base64
let n = bytes.length;
const ia = new Uint8Array(n);
while (n--) {
ia[n] = bytes.charCodeAt(n);
}
return new File([ia], fileName, { type: mime });
},
handleRemove(file) {
// 从列表中删除当前的图片
var that = this;
try {
var delname = file.url.split('/');
that.formInline.files = that.formInline.files.filter((ele) => {
var name = ele.name.split('/');
return name[name.length - 1] !== delname[delname.length - 1];
});
console.log(that.formInline.files);
} catch (error) {}
},
OnChange(file, fileList) {
console.log(file, fileList, '多选情况下传参');
const isType = file.type === 'image/jpeg' || 'image/png';
const isLt5M = file.size / 1024 / 1024 < 5;
if (!isType) {
this.$message.error('上传图片只能是 JPG 格式!');
fileList.pop();
}
if (!isLt5M) {
this.$message.error('上传图片大小不能超过 5MB!');
fileList.pop();
}
this.formInline.files.push(file.raw);
},
async setCompanySubmit() {
let formData = new FormData(); // 用FormData存放上传文件
this.formInline.files.forEach((file, index) => {
formData.append('files', file);
});
let { name, tel, truename, id } = this.formInline;
formData.append('name', name);
formData.append('tel', tel);
formData.append('truename', truename);
formData.append('id', id);
const res = await Api_setCompany(formData);
if (res.code == 200) {
this.$message.success('成功!!!');
this.unitDialogVisible = false;
this.fileImgList = [];
this.$refs.uploadCompanyRef.clearFiles();
}
}
}
};
</script>
<style lang="scss" scoped></style>
6.照片墙效果
文章到此结束,希望对你有所帮助~