这是一个很常见的需求,但是我在写代码的过程中发现一些坑,就想为大家(包括踩坑前的我)打开一扇大门,话不多说,上才艺。
html部分用到vant UI库的van-uploader
<!-- 上传附件 -->
<div class="uploadImg">
<span class="isMust">*</span>
<p class="uploadImg-title">4、附件上传(最多上传9张)</p>
<van-uploader
:after-read="onRead"
:accept="'image/*'"
v-model="fileList"
multiple
@delete="delImg"
:max-count="9"
/>
</div>
js的data部分:
data() {
return {
fileList: [],
};
},
分两种情况:
1、单张图片上传,注意此时传过来的file是对象,以下就是针对对象的处理方法
下面的代码可直接搬哈,只是把存图片地址的 fileList替换成自己的参数即可,具体就是先判断当前图片大小,如果>1M,就要压缩再上传:
// 图片上传后
onRead(file) {
console.log("上传的file", file);
// 大于1MB的jpeg和png图片都缩小像素上传
file.status = "uploading";
file.message = "上传中...";
// 如果是单张图片,fille是对象,当上传图片大于1M时,压缩上传
if (file.file) {
if (
/\/(?:jpeg|png)/i.test(file.file.type) &&
file.file.size > 1000000
) {
console.log("大于1Mb");
// 创建Canvas对象(画布)
let canvas = document.createElement("canvas");
// 获取对应的CanvasRenderingContext2D对象(画笔)
let context = canvas.getContext("2d");
// 创建新的图片对象
let img = new Image();
// 指定图片的DataURL(图片的base64编码数据)
img.src = file.content;
// 监听浏览器加载图片完成,然后进行进行绘制
img.onload = () => {
var newWidth = img.width * 0.7; //压缩后图片的宽度
var newHeight = img.height * 0.7; //压缩后图片的高度
// 指定canvas画布大小,该大小为最后生成图片的大小
canvas.width = newWidth;
canvas.height = newHeight;
/* drawImage画布绘制的方法。(0,0)表示以Canvas画布左上角为起点,400,300是将图片按给定的像素进行缩小。
如果不指定缩小的像素图片将以图片原始大小进行绘制,图片像素如果大于画布将会从左上角开始按画布大小部分绘制图片,最后的图片就是张局部图。*/
context.drawImage(img, 0, 0, newWidth, newHeight);
// 将绘制完成的图片重新转化为base64编码,file.file.type为图片类型,0.92为默认压缩质量
file.content = canvas.toDataURL(file.file.type, 0.7);
let data = {
dirtype: "hlfw",
message: file.content,
};
// 以下是请求
// this.$post("/uploadImg", data)
// .then((res) => {
// if (res.result == "success") {
// file.uploadUrl = res.url;
// this.$toast(res.info);
// file.status = "";
// file.message = "";
// } else {
// this.$toast(res.info);
// file.status = "failed";
// file.message = "上传失败";
// if (!this.fileList[this.fileList.length - 1].uploadUrl) {
// this.fileList.splice(this.fileList.length - 1, 1);
// }
// }
// })
// .catch((err) => {
// console.log(err);
// this.$toast("上传超时 请重试");
// file.status = "failed";
// file.message = "上传失败";
// if (!this.fileList[this.fileList.length - 1].uploadUrl) {
// this.fileList.splice(this.fileList.length - 1, 1);
// }
// });
};
} else {
let data = {
dirtype: "hlfw",
message: file.content,//这里可以这样传message 也可以直接传this.fileList.content(具体参数根据后端需求来写)
};
console.log("jijik", data,this.fileList);
// this.$post("/uploadImg", data)
// .then((res) => {
// console.log("从v", res);
// if (res.result == "success") {
// file.uploadUrl = res.url;
// file.status = "";
// file.message = "";
// } else {
// this.$toast(res.info);
// file.status = "failed";
// file.message = "上传失败";
// if (!this.fileList[this.fileList.length - 1].uploadUrl) {
// this.fileList.splice(this.fileList.length - 1, 1);
// }
// }
// })
// .catch((err) => {
// console.log(err);
// console.log(this.fileList);
// file.status = "failed";
// file.message = "上传失败";
// this.$toast("上传超时 请重试");
// if (!this.fileList[this.fileList.length - 1].uploadUrl) {
// this.fileList.splice(this.fileList.length - 1, 1);
// }
// });
}
}else(){
// 这里是多条上传处理方式,根据自己需求搬
},
以上就是单条上传,接下来说说批量上传,以下方法适用于,后端要求接收参数为对象(数组就不要for循环上传了)这里就是上面else里面的内容拉,我拆分来写,各位各取所需
// 如果是批量,file就是数组
else {
for (let i = 0; i < file.length; i++) {
if (
/\/(?:jpeg|png)/i.test(file[i].file.type) &&
file[i].file.size > 1000000
) {
console.log("大于1Mb");
// 创建Canvas对象(画布)
let canvas = document.createElement("canvas");
// 获取对应的CanvasRenderingContext2D对象(画笔)
let context = canvas.getContext("2d");
// 创建新的图片对象
let img = new Image();
// 指定图片的DataURL(图片的base64编码数据)
img.src = file[i].content;
// 监听浏览器加载图片完成,然后进行进行绘制
img.onload = () => {
var newWidth = img.width * 0.7; //压缩后图片的宽度
var newHeight = img.height * 0.7; //压缩后图片的高度
// 指定canvas画布大小,该大小为最后生成图片的大小
canvas.width = newWidth;
canvas.height = newHeight;
/* drawImage画布绘制的方法。(0,0)表示以Canvas画布左上角为起点,400,300是将图片按给定的像素进行缩小。
如果不指定缩小的像素图片将以图片原始大小进行绘制,图片像素如果大于画布将会从左上角开始按画布大小部分绘制图片,最后的图片就是张局部图。*/
context.drawImage(img, 0, 0, newWidth, newHeight);
// 将绘制完成的图片重新转化为base64编码,file.file.type为图片类型,0.92为默认压缩质量
file[i].content = canvas.toDataURL(file[i].file.type, 0.7);
let data = {
dirtype: "hlfw",
message: file[i].content,
};
// this.$post("/uploadImg", data)
// .then((res) => {
// if (res.result == "success") {
// file.uploadUrl = res.url;
// this.$toast(res.info);
// file.status = "";
// file.message = "";
// } else {
// this.$toast(res.info);
// file.status = "failed";
// file.message = "上传失败";
// if (!this.fileList[this.fileList.length - 1].uploadUrl) {
// this.fileList.splice(this.fileList.length - 1, 1);
// }
// }
// })
// .catch((err) => {
// console.log(err);
// this.$toast("上传超时 请重试");
// file.status = "failed";
// file.message = "上传失败";
// if (!this.fileList[this.fileList.length - 1].uploadUrl) {
// this.fileList.splice(this.fileList.length - 1, 1);
// }
// });
};
} else {
let data = {
dirtype: "hlfw",
message: this.fileList[i].content,
};
console.log("上传参数", data,'图片参数',this.fileList[i]);
this.$post("/uploadImg", data)
.then((res) => {
console.log("从v", res);
if (res.result == "success") {
file[i].uploadUrl = res.url;
file[i].status = "";
file[i].message = "";
} else {
this.$toast(res.info);
file[i].status = "failed";
file[i].message = "上传失败";
if (!this.fileList[this.fileList.length - 1].uploadUrl) {
this.fileList.splice(this.fileList.length - 1, 1);
}
}
})
.catch((err) => {
console.log(err);
console.log(this.fileList);
file[i].status = "failed";
[i].message = "上传失败";
this.$toast("上传超时 请重试");
if (!this.fileList[this.fileList.length - 1].uploadUrl) {
this.fileList.splice(this.fileList.length - 1, 1);
}
});
}
}
}
其实呢,跟单张大同小异,只是我们这里的file接收到的是个数组,所以采用for轮询发请求上传的方式(再说一次:这是后端不接收数组的方式哈,如果你打得赢他,让他接收数组,方便一点)
至此完结,早日暴富,脱离苦海