这是我的千日蜕变计划第三篇,我计划在未来的1000天,三天更新一篇博客。希望大家监督,也希望自己可以坚持。
功能分析
- 利用element-ui的图片上传组件实现多图上传
- 前端实现图片压缩(等比例压缩或者质量压缩不缩放百分比)
html部分代码
// 这里我把element-ui的上传组件隐藏,用了一个单独的按钮调用上传的方法
<el-upload
multiple
style="display: none;"
:action="updateImgUrl"
:before-upload="beforeAvatarUpload"
:on-success="handleAvatarSuccess"
:on-error="handleAvatarError">
<button ref="trueUpdateFile" size="small" type="primary">点击上传</button>
</el-upload>
<button ref="trueUpdateFile" size="small" type="primary">点击上传</button>
JS代码部分
export default {
data() {
return {
imgQuality: 0.5 //压缩图片的质量
}
}
methods: {
// 上传文件
handleUpdateFile() {
this.$refs['trueUpdateFile'].click()
},
// 上传之前
beforeAvatarUpload(file) {
const isJPGORPNG = file.type === 'image/jpeg' || file.type === 'image/png';
const isLt10M = file.size / 1024 / 1024 < 10;
const imgSize = file.size / 1024 / 1024;
// 这里根据不同的图片质量,使用不同的压缩比例
if (imgSize > 2) {
this.imgQuality = 0.3;
} else if(imgSize > 1) {
this.imgQuality = 0.5;
} else if(imgSize > 0.2) {
this.imgQuality = 0.8;
} else {
this.imgQuality = 1;
}
this.tempimgNum++;
if (!isJPGORPNG) {
this.uploadTips = '上传';
this.updateLoading = false;
common.showMessage(Message, '上传头像图片只能是 JPG 格式或者png格式!', 'error', '1000', function () {});
}
if (!isLt10M) {
this.uploadTips = '上传';
this.updateLoading = false;
common.showMessage(Message, '上传头像图片大小不能超过 10MB!', 'error', '1000', function () {});
}
const _this = this
if(imgSize > 1) {
return new Promise(resolve => {
const reader = new FileReader()
const image = new Image()
image.onload = (imageEvent) => {
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
const width = image.width; // 如果需要等比例压缩,这里*质量。image.width * this.imgQuality.高度也这样操作
const height = image.height;
canvas.width = width;
canvas.height = height;
context.clearRect(0, 0, width, height);
context.drawImage(image, 0, 0, width, height);
const dataUrl = canvas.toDataURL(file.type, this.imgQuality);
//如果需要等比例压缩,这里
//const dataUrl = canvas.toDataURL(file.type);
const blobData = _this.dataURItoBlob(dataUrl, file.type);
resolve(blobData)
}
reader.onload = (e => { image.src = e.target.result; });
reader.readAsDataURL(file);
})
}
return isJPGORPNG && isLt10M;
},
dataURItoBlob(dataURI, type) {
var binary = atob(dataURI.split(',')[1]);
var array = [];
for(var i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i));
}
return new Blob([new Uint8Array(array)], {type: type});
},
handleAvatarSuccess(res) {
if(res) {
this.attachIds.push(res)
}
// 这里判断多图是否上传完成
if(this.tempimgNum === this.attachIds.length) {
this.uploadTips = '';
this.getReceptionId()
}
},
handleAvatarError() {
this.updateLoading = false;
},
getReceptionId() {
let formData = common.getFormFormatData({patientId: this.childData.patientId});
axios({
method: 'post',
url: this.getPatientLastId,
data: formData,
config: common.getFormHeaders()
}).then((res) => {
this.handleSavePatientAttach(res.data)
}).catch((e) => {
common.showMessage(Message, e.response.data.message, 'error', '1000', function () {});
}).finally(() => {
this.updateLoading = false;
this.uploadTips = '上传';
});
},
// 最后确认保存
handleSavePatientAttach(reception_id) {
let attach_ids = this.attachIds.join(',');
let formData = common.getFormFormatData({
patientId: this.childData.patientId,
attachIds: attach_ids,
receptionId: reception_id,
description: ''
});
axios({
method: 'post',
url: this.savePatientAttachUrl,
data: formData,
config: common.getFormHeaders()
}).then((res) => {
common.showMessage(Message, '图片上传成功', 'success', '1000', () => {
this.radioClick()
});
}).catch((e) => {
common.showMessage(Message, e.response.data.message, 'error', '1000', () => {
});
}).finally(() => {
// 上传结束后,初始化临时数据
this.tempimgNum = 0;
this.attachIds = [];
this.loading = false;
this.updateLoading = false;
this.uploadTips = '上传';
});
},
}
}
以上代码有很多涉及到业务代码。主要用来留存前端压缩图片的方法。
我是海明月,前端小学生。