1. 安装
npm i vue-cropper
2. 使用
2.1 单独封装插件
|-src
|-|-plugins
|-|-|-vue-croppper.js
import Vue from 'vue';
import VueCropper from 'vue-cropper';
Vue.use(VueCropper);
2.2 main.js中
import './plugins/vue-cropper';// 图片裁剪插件
3 封装组件为by-cropper
3.1 template
/* 图片裁剪 */
<template>
<div class="vue-cropper-box">
<div class="vue-cropper-header">
<p class="title">图片裁剪</p>
<i type="primary" class="el-icon-close" @click="close()"></i>
</div>
<div class="vue-cropper-operate">
<button class="basicButton" @click="cropperChangeScale(1)">放大</button>
<button class="basicButton" @click="cropperChangeScale(-1)">缩小</button>
<button class="basicButton" @click="cropperRotateLeft">左旋转</button>
<button class="basicButton" @click="cropperRotateRight">右旋转</button>
<button class="basicButton" @click="cropperDown('blob')">下载</button>
<button class="basicButton" @click="cropperFinish">确定裁剪</button>
</div>
<div class="vue-cropper-content">
<vueCropper
ref="cropper"
:img="cropperOption.img"
:outputSize="cropperOption.outputSize"
:outputType="cropperOption.outputType"
:info="cropperOption.info"
:full="cropperOption.full"
:canMove="cropperOption.canMoveBox"
:canMoveBox="cropperOption.canMoveBox"
:original="cropperOption.original"
:canScale="cropperOption.canScale"
:autoCrop="cropperOption.autoCrop"
:autoCropWidth="cropperOption.autoCropWidth"
:autoCropHeight="cropperOption.autoCropHeight"
:fixed="cropperOption.fixed"
:fixedNumber="cropperOption.fixedNumber"
@realTime="realTime"
@imgLoad="imgLoad"
></vueCropper>
</div>
</div>
</template>
3.2 script
<script>
export default {
name: 'by-cropper',
components: {},
inject: ['reload'],
filters: {},
props: {
file: {
default: () => {},
required: true
},
cropperOption: {
default: () => ({
img: '', // 裁剪图片的地址
info: true, // 裁剪框的大小信息
outputSize: 1, // 裁剪生成图片的质量
full: false, // 输出原图比例截图 props名full
outputType: 'jpeg', // 裁剪生成图片的格式
canMove: true, // 能否拖动图片
original: false, // 上传图片是否显示原始宽高
canMoveBox: true, // 能否拖动截图框
canScale: false, // 图片是否允许滚轮缩放
autoCrop: true, // 是否默认生成截图框
autoCropWidth: 400, // 默认生成截图框宽度
autoCropHeight: 300, // 默认生成截图框高度
fixedBox: false, // 截图框固定大小
fixed: true, // 是否开启截图框宽高固定比例
fixedNumber: [4, 3] // 截图框的宽高比例
})
}
},
data() {
return {
};
},
computed: {
// computeFunction() {
// return value;
// }
},
watch: {
},
created() {
// this.init();
},
mounted() {
// this.init();
},
methods: {
// ---------------图片裁剪功能-开始---------------
cropperChangeScale(num) {
num = num || 1;
this.$refs.cropper.changeScale(num);
},
// 左旋转
cropperRotateLeft() {
this.$refs.cropper.rotateLeft();
},
// 右旋转
cropperRotateRight() {
this.$refs.cropper.rotateRight();
},
// 下载图片
cropperDown(type) {
console.log('down');
let aLink = document.createElement('a');
aLink.download = 'author-img';
if (type === 'blob') {
this.$refs.cropper.getCropBlob(data => {
this.downImg = window.URL.createObjectURL(data);
aLink.href = window.URL.createObjectURL(data);
aLink.click();
});
} else {
this.$refs.cropper.getCropData(data => {
this.downImg = data;
aLink.href = data;
aLink.click();
});
}
},
// 确定裁剪
cropperFinish(type) {
if (type === 'Blob') {
this.$refs.cropper.getCropBlob((data) => {
let file = data;
file.name = this.file.name;
this.$emit('cropperFinish', file, data);
});
} else {
this.$refs.cropper.getCropData(data => {
// 将剪裁后base64的图片转化为file格式
let file = this.convertBase64UrlToBlob(data);
file.name = this.file.name;
this.$emit('cropperFinish', file, data);
});
}
},
// 将base64的图片转换为file文件
convertBase64UrlToBlob(urlData) {
let bytes = window.atob(urlData.split(',')[1]); // 去掉url的头,并转换为byte
// 转化为base64
// reader.readAsDataURL(file)
// 转化为blob
// 处理异常,将ascii码小于0的转换为大于0
let ab = new ArrayBuffer(bytes.length);
let ia = new Uint8Array(ab);
for (let i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i);
}
return new Blob([ab], { type: 'image/jpeg' });
},
// 实时预览函数
realTime(data) {
// console.log('realTime');
},
// 图片已加载
imgLoad(msg) {
// console.log('imgLoad');
// console.log(msg);
},
close() {
this.$emit('close');
}
}
};
</script>
3.3 style 样式仅供参考
<style lang="less" scoped>
// 基础按钮
.basicButton {
font-size: @font-size-m;
padding: 0 0.1rem;
line-height: 0.4rem;
border: none;
border-radius: @border-radius-middle;
color: #fff;
background: @base-color-blue;
&:not(:last-child) {
margin-right: 0.2rem;
}
&.disabled {
opacity: 0.5;
}
&.cancel{
background: @base-color-grey;
}
&.warning {
background: @base-color-red;
}
&.black {
background-color: @base-color-black;
}
}
/* 图片裁剪工具 */
.vue-cropper-box{
z-index: 3001;
position: absolute;
top: 0;
width: 100%;
height: 95%;
background: #fff;
.vue-cropper-operate{
display: flex;
align-items: center;
justify-content: center;
padding: 0.2rem;
}
.vue-cropper-content{
width: 100%;
height:calc(100% - 1rem);
position: relative;
overflow-y: auto;
.vue-cropper{
position: absolute;
}
}
}
</style>
4. 使用组件
4.1 template片段
<div v-if="isShowCropper">
<by-cropper
:cropperOption="cropperOption"
:file="cropperFile"
@cropperFinish="cropperFinish"
@close="()=>{isShowCropper=false}"
></by-cropper>
</div>
4.2 script片段
vuex
中的上传接口,接口如何写可以参考文章【Vue教程】Vue Cli3项目结构优化和【Vue教程】vuex、axios请求接口的几种方式
import ByCropper from '@/components/common/ByCropper';
export default {
data() {
return {
/* vue-cropper 配置信息 */
isShowCropper: false, // 是否显示-图片裁剪-弹窗
cropperFile: {}, // 当前待裁剪图片的文件信息
cropperOption: {
img: '', // 裁剪图片的地址
info: true, // 裁剪框的大小信息
outputSize: 1, // 裁剪生成图片的质量
full: false, // 输出原图比例截图 props名full
outputType: 'jpeg', // 裁剪生成图片的格式
canMove: true, // 能否拖动图片
original: false, // 上传图片是否显示原始宽高
canMoveBox: true, // 能否拖动截图框
canScale: false, // 图片是否允许滚轮缩放
autoCrop: true, // 是否默认生成截图框
autoCropWidth: 400, // 默认生成截图框宽度
autoCropHeight: 300, // 默认生成截图框高度
fixedBox: false, // 截图框固定大小
fixed: true, // 是否开启截图框宽高固定比例
fixedNumber: [4, 3] // 截图框的宽高比例
},
methods:{
// 以下方法可以根据 封装组件 this.$emit('cropperFinish', file, data); 中获取的 file data 自定义进行处理
// 获取到文件时,进行如下处理
handleFile(file){
this.cropperFile = file;
this.cropperOption.img = file.src;
this.isShowCropper = true;
},
// 确定裁剪
cropperFinish(file) {
// 请求接口-上传文件
this.postUploadFile(file);
},
// 文件上传-接口-上传文件
postUploadFile(file) {
console.log('PostUploadFile>', file);
let formData = new FormData();
formData.append('file', file, file.name);
// vuex 中的上传接口,接口如何写可以参考文章[杀杀杀]()
this.uploadFileCase(formData).then(res => {
console.log('uploadFileCase>', file);
if (res.code === 1) {
// 自定义操作
// this.fileList.push({
// name: file.name,
// src: file.src,
// filePath: res.data,
// file: file
// });
// this.ruleForm.imgPath = res.data;
// this.ruleForm.file = file;
this.isShowCropper = false;
this.cropperOption.img = null;
this.cropperFile = {};
}
});
},
},
}
}
}
参考文档网址:
一个优雅的图片裁剪插件:vue-cropper
Vue项目图片剪切上传——vue-cropper的使用
vue使用vue-cropper实现裁剪、上传、下载功能