封装 vue 基于van-uploader图片压缩后上传组件
需安装van-uploader、html2canvas
<template>
<div class="upload_control">
<div class="control_btn">
<van-uploader class="upload" :after-read="afterRead" capture="camera" accept="image/*">
<a class="shot_btn">拍照</a>
</van-uploader>
<a class="cancel_btn" @click="cancelUpload">取消</a>
</div>
<div class="canvas_content" v-if="canvasUrl">
<div class="canvas" ref="canvasContent"><img :src="canvasUrl" ref="canvasImg"></div>
</div>
</div>
</template>
<script>
import html2canvas from 'html2canvas'
export default {
name: "upLoad",
data() {
return {
canvasUrl: ''
}
},
methods: {
afterRead(file) {
this.canvasUrl = file.content
let fileSize = file.file.size/1024/0.7 //注意:图片流质量大小约为base64格式质量大小的70%
let limitSize = 2*1024 //2M大小限制
if(fileSize > limitSize){
this.$nextTick(() => { //确保获取到dom元素
let canvasImg = this.$refs.canvasImg
canvasImg.onload = () => { //确保图片已渲染完成
let canvasContent = this.$refs.canvasContent
html2canvas(canvasContent, {
dpi: window.devicePixelRatio * 2,
scale: 2,
width: canvasContent.offsetWidth,
height: canvasContent.offsetHeight,
scrollY: 0,
scrollX: 0,
useCORS: true
}).then(canvas => {
let quality = (limitSize / fileSize).toFixed(2)
let url = canvas.toDataURL('image/jpeg', quality) //注意:toDataURL方法必须指定图片格式为jpeg和webp,否则quality图片质量参数默认为0.92
this.uploadImg(url)
}).catch(()=> {
this.$toast('上传图片超过2M')
})
}
})
}else{
this.uploadImg(file.content)
}
},
uploadImg(baseUrl) {
let img = encodeURIComponent(baseUrl.trim())
this.API.imgDiscern(img).then(res => { //封装的上传图片接口
let info = {
echoUrl: baseUrl,
...res
}
this.$emit('updateFile', JSON.stringify(info))
}).catch(err => {
this.$toast(err.errorMsg)
this.canvasUrl = ''
})
},
cancelUpload() {
this.$emit('cancelUpload')
}
}
}
</script>
<style scoped lang="less">
.upload_control{
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 2000;
display: flex;
align-items: flex-end;
background: rgba(0, 0, 0, 0.5);
}
.control_btn{
.flex(@direction: column);
width: 100%;
background: #fff;
.shot_btn, .cancel_btn{
.flex(@align: center);
width: 100%;
height: 55px;
font-size: 20px;
color: #444D54;
border-bottom: 1px solid #d1d1d1;
}
.cancel_btn{
border-bottom: 0;
}
}
.upload{
width: 100%;
height: 55px;
}
/deep/.van-uploader__input-wrapper{
width: 100%;
height: 100%;
}
.canvas_content{
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
opacity: 0;
.canvas{
width: 100%;
img{
width: 100%;
height: auto;
}
}
}
</style>