vant有赞的 Vue 组件库上传图片显示进度条

上传图片,显示进度条,转换base64,旋转图片,
1.先下载安装
2.引入

import Vue from 'vue';
	import Exif from 'exif-js'
	import {Uploader} from 'vant';
	Vue.use(Uploader);
	import 'vant/lib/uploader/style';

3.配置使用到的属性 和 使用的方法

export default {
    data(){
    //配置使用到的属性
    	return{
    			progress: 0,
                loading: false,
    	}
    }
    //用到的方法,直接复制放进需要的位置
	methods:{
 		checkCount: function (file) {
            this.isok = true;
            var self = this;
            Exif.getData(file, function () {
                self.Orientation = Exif.getTag(this, 'Orientation');
            });
            return true;
        },
        addContent(file) {
            this.loading=true;
            this.num = 0;
            if (!this.isok) {
           		return false;
            }
            let self = this;
            let result = file.content;
            let img = new Image();
            img.src = result;
            if (result.length <= (100 * 1024)) {
            	self.uploadimg(file.content);
            } else {   
           		img.onload = function () {
	                let data = self.compress(img, self.Orientation);
	                self.uploadimg(data);
            	}
	        }
	    },
		uploadimg: function (data) {
            var config = {
            onUploadProgress: progressEvent => {
                var complete = progressEvent.loaded / progressEvent.total
                if (this.num == 1) {
                    this.progress1 = complete
                } else if (this.num == 2) {
                    this.progress2 = complete
                } else if (this.num == 0) {
                    this.progress = complete
                } 
            }
            }
            this.axios.post(CONSTANT.IMGUPLOAD_URL+"/file/saveImage4Base64", {
            path: '/jjrenter/',
            content: data
            }, config).then(res => {
                if (res.data.code == 0) {
                    if (this.num == 1) {
                        this.jjrInformation.idcardimg1  = res.data.data;
                    } else if (this.num == 2) {
                        this.jjrInformation.idcardimg2  = res.data.data;
                    } else if (this.num == 0) {
                        this.jjrInformation.businesslicence  = res.data.data;
                    } 
                } else {
                    this.$dialog.toast({
                    mes: '文件上传失败',
                    timeout: 1500,
                    icon: 'error'
                    });
                }
                if (this.num == 1) {
                    this.loading1 = false;
                } else if (this.num == 2) {
                    this.loading2 = false;
                } else if (this.num == 0) {
                    this.loading = false;
                }
            })
        },
        compress(img, Orientation) {
            let canvas = document.createElement("canvas");
            let ctx = canvas.getContext('2d');
            //瓦片canvas
            let tCanvas = document.createElement("canvas");
            let tctx = tCanvas.getContext("2d");
            let initSize = img.src.length;
            let width = img.width;
            let height = img.height;
            //如果图片大于四百万像素,计算压缩比并将大小压至400万以下
            let ratio;
            if ((ratio = width * height / 4000000) > 1) {
                console.log("大于400万像素")
                ratio = Math.sqrt(ratio);
                width /= ratio;
                height /= ratio;
            } else {
                ratio = 1;
            }
            canvas.width = width;
            canvas.height = height;
            //        铺底色
            ctx.fillStyle = "#fff";
            ctx.fillRect(0, 0, canvas.width, canvas.height);
            //如果图片像素大于100万则使用瓦片绘制
            let count;
            if ((count = width * height / 1000000) > 1) {
                console.log("超过100W像素");
                count = ~~(Math.sqrt(count) + 1); //计算要分成多少块瓦片
                //            计算每块瓦片的宽和高
                let nw = ~~(width / count);
                let nh = ~~(height / count);
                tCanvas.width = nw;
                tCanvas.height = nh;
                for (let i = 0; i < count; i++) {
                    for (let j = 0; j < count; j++) {
                    tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh);
                    ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh);
                    }
                }
            } else {
                ctx.drawImage(img, 0, 0, width, height);
            }
            //修复ios上传图片的时候 被旋转的问题
            if (Orientation != "" && Orientation != 1) {
            
	            switch (Orientation) {
	                case 6: //需要顺时针(向左)90度旋转
	                	this.rotateImg(img, 'left', canvas);
	                	break;
	                case 8: //需要逆时针(向右)90度旋转
	                	this.rotateImg(img, 'right', canvas);
	                	break;
	                case 3: //需要180度旋转
	                	this.rotateImg(img, 'right', canvas); //转两次
	                	this.rotateImg(img, 'right', canvas);
	               		break;
	            }
        	}
            //进行最小压缩
            let ndata = canvas.toDataURL('image/jpeg', 0.1);
            tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0;
            return ndata;
        },
        rotateImg(img, direction, canvas) {
            //最小与最大旋转方向,图片旋转4次后回到原方向
            const min_step = 0;
            const max_step = 3;
            if (img == null) return;
            //img的高度和宽度不能在img元素隐藏后获取,否则会出错
            let height = img.height;
            let width = img.width;
            let step = 2;
            if (step == null) {
            	step = min_step;
            }
            if (direction == 'right') {
            	step++;
            	//旋转到原位置,即超过最大值
            	step > max_step && (step = min_step);
            } else {
	            step--;
	            step < min_step && (step = max_step);
            }
        //旋转角度以弧度值为参数
            let degree = step * 90 * Math.PI / 180;
            let ctx = canvas.getContext('2d');
            switch (step) {
            case 0:
                canvas.width = width;
                canvas.height = height;
                ctx.drawImage(img, 0, 0);
                break;
            case 1:
                canvas.width = height;
                canvas.height = width;
                ctx.rotate(degree);
                ctx.drawImage(img, 0, -height);
                break;
            case 2:
                canvas.width = width;
                canvas.height = height;
                ctx.rotate(degree);
                ctx.drawImage(img, -width, -height);
                break;
            case 3:
                canvas.width = height;
                canvas.height = width;
                ctx.rotate(degree);
                ctx.drawImage(img, -width, 0);
                break;
            }
        },
  	}
}
4.页面渲染
<van-uploader :before-read="checkCount" :after-read="addContent" multiple>
    <div class="upload" v-if="!loading">
         <img v-if="jjrInformation.businesslicence ==null||jjrInformation.businesslicence ==''" src="../../../static/img/upload.png"/>
         //( jjrInformation.businesslicence 这个是我接口返回的图片的值。自行修改。)
         <span id="imgpic" v-else :style="{backgroundImage: 'url(' + jjrInformation.businesslicence  + ')', backgroundSize:'contain',backgroundRepeat:'no-repeat',backgroundPosition:'center center'}"></span>
         // (这里为了让图片水平垂直居中,用了背景图的方式,根据各自需要就可以了)
    </div>
    <div v-if="loading" style="width: 100%;height: 100%;">
        <yd-progressbar :progress="progress" trail-width="4">
            <yd-countup  :endnum="progress * 100" :duration="1" suffix="%"></yd-countup>
        </yd-progressbar>
    </div>
</van-uploader>

效果图:
在这里插入图片描述
在这里插入图片描述
到这就可以了
可以复制进去自己试试,也可以将这个封装成组件,需要使用的地方引入组件就可以了

猜你喜欢

转载自blog.csdn.net/MtangEr/article/details/88821022