1.安裝 :npm i cropperjs

image.png
3.最好寫(xiě)成一個(gè)組件,隨時(shí)調(diào)用
<template>
<div class="v-simple-cropper">
<input class="file" type="file" accept="image/*" @change="uploadChange" />
<div class="v-cropper-layer" ref="layer" v-show="showlayer">
<div class="layer-header">
<button class="cancel" @click="cancelHandle">取消</button>
<button class="confirm" @click="confirmHandle">選取</button>
</div>
<img ref="cropperImg" />
</div>
</div>
</template>
import Cropper from 'cropperjs';
import 'cropperjs/dist/cropper.min.css';
import * as qiniu from 'qiniu-js';
private cropper: any;
// 裁剪板塊
private showlayer = false;
// 裁剪參數(shù)
private initParam = {
scale: 1 // 相對(duì)手機(jī)屏幕放大的倍數(shù)
};
// 初始化裁剪插件
private init() {
const cropperImg = this.$refs.cropperImg as HTMLImageElement;
this.cropper = new Cropper(cropperImg, {
aspectRatio: 1 / 1, // 剪裁比例
dragMode: 'move' // 模式
});
}
// 選擇上傳文件
private uploadChange(e) {
const file = e.target.files[0];
this.showlayer = true;
const URL = window.URL || window.webkitURL;
this.cropper.replace(URL.createObjectURL(file));
}
// 取消上傳
private cancelHandle() {
this.cropper.reset();
this.showlayer = false;
}
// 確定上傳
private confirmHandle() {
const cropBox = this.cropper.getCropBoxData();
const scale = this.initParam['scale'] || 1;
this.cropper
.getCroppedCanvas({
width: cropBox.width * scale,
height: cropBox.height * scale
})
//把裁剪的圖片轉(zhuǎn)換成blob類型文件,在通過(guò)new File(),轉(zhuǎn)換成file文件
.toBlob(async blob => {
//重置file的name,以時(shí)間戳作為文件名
const timeString = new Date().getTime();
const imgFile = new File([blob], `${timeString}.jpg`, { type: 'image/jepg' });
this.showlayer = false;
const res = await this.uploadFile(imgFile);
this.$emit('uploadURL', res);
});
}
// 請(qǐng)求接口上傳圖片
private uploadFile(file) {
return new Promise(resolve => {
msg.PostQiniu().then(res => {
const uptoken = res.token;
const key = file.name;
const config = {
useCdnDomain: false, //表示是否使用 cdn 加速域名,為布爾值,true 表示使用,默認(rèn)為 false。
region: undefined // 根據(jù)具體提示修改上傳地區(qū),當(dāng)為 null 或 undefined 時(shí),自動(dòng)分析上傳域名區(qū)域
};
const putExtra: any = {
fname: file.name, //文件原文件名
params: {}, //用來(lái)放置自定義變量
mimeType: ['image/png', 'image/jpeg', 'image/gif'] //用來(lái)限制上傳文件類型,為 null 時(shí)表示不對(duì)文件類型限制;
};
const observable = qiniu.upload(file, key, uptoken, putExtra, config);
observable.subscribe({
next: result => {
// 主要用來(lái)展示進(jìn)度
console.warn(result);
},
error: () => {
this.$toast.show('提交失敗');
},
complete: e => {
resolve(`${res.domain}${e.key}`);
}
});
});
});
}
4.樣式
<style lang="scss" scoped>
@import '@/assets/style/color.scss';
.v-simple-cropper {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
.file {
width: 100%;
height: 100%;
opacity: 0;
}
.v-cropper-layer {
position: fixed;
width: 100%;
height: 100%;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: #fff;
z-index: 99999;
.layer-header {
position: absolute;
top: 0;
left: 0;
z-index: 99999;
background: rgba(#fff, 0.5);
width: 100%;
height: 0.8rem;
padding: 0 0.2rem;
box-sizing: border-box;
}
.cancel,
.confirm {
line-height: 0.8rem;
font-size: 0.28rem;
background: none;
border: 0;
outline: 0;
float: left;
}
.confirm {
float: right;
}
img {
position: inherit !important;
border-radius: inherit !important;
float: inherit !important;
}
}
}
</style>
5.在頁(yè)面調(diào)用組件
<cropperBox @uploadURL="uploadURL" />
// 上傳成功 獲取img
private uploadURL(url) {
console.log(url);
}