# 利用vue-cropper实现图片裁剪功能
# 安装
npm install vue-cropper
# 基于el-dialog实现裁剪组件
<template>
<div class="cropper_model">
<el-dialog title="图片剪裁" width="900px" class="cropper_model_dlg" :visible.sync="dialogVisible" append-to-body :close-on-click-modal="false" :close-on-press-escape="false">
<div class="cropper_content">
<div class="cropper" style="text-align: center;">
<vueCropper ref="cropper" :img="options.img" :outputSize="options.outputSize" :outputType="options.outputType" :info="options.info" :canScale="options.canScale" :autoCrop="options.autoCrop" :autoCropWidth="options.autoCropWidth" :autoCropHeight="options.autoCropHeight" :fixed="options.fixed" :fixedBox="options.fixedBox" :fixedNumber="options.fixedNumber" @realTime="previewImg">
</vueCropper>
<div class="cropper_btns">
<el-button type="primary" @click="goUpload" size="mini">
重新上传
</el-button>
<el-button @click="rotateLeft" icon="el-icon-refresh-left" size="mini" title="左旋转"></el-button>
<el-button @click="rotateRight" icon="el-icon-refresh-right" size="mini" title="右旋转"></el-button>
<el-button @click="changeScale(1)" icon="el-icon-zoom-in" size="mini" title="放大"></el-button>
<el-button @click="changeScale(-1)" icon="el-icon-zoom-out" size="mini" title="缩小"></el-button>
</div>
</div>
<div class="cropper_right">
<h3>预览</h3>
<!-- 预览 -->
<div class="cropper_preview" :style="{
width: preview.w + 'px',
height: preview.h + 'px',
overflow: 'hidden',
margin: '5px'
}">
<div :style="preview.div">
<img :src="preview.url" :style="preview.img" alt="" />
</div>
</div>
</div>
</div>
<div slot="footer" class="dialog-footer">
<el-button size="small" @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" size="small" :loading="loading" @click="uploadImg">确定上传</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { VueCropper } from "vue-cropper";
export default {
unAutoRegister: true, //不自动注册组件
components: { VueCropper },
props: {
//加载状态
loading: {
type: Boolean,
default: false
}
},
data() {
return {
dialogVisible: false,
options: {
img: "", // 裁剪图片的地址
outputSize: 1, // 裁剪生成图片的质量
outputType: "png", // 裁剪生成图片的格式
info: true, // 裁剪框的大小信息
canScale: true, // 图片是否允许滚动缩放
autoCrop: true, // 是否默认生成截图狂
autoCropWidth: 300, // 默认生成截图框宽度
autoCropHeight: 300, // 默认生成截图框高度
fixed: true, // 是否开启截图框宽高固定比例
fixedNumber: [1, 1], // 截图框的宽高比例
full: true, // 是否输出原图比例的截图
fixedBox: false, // 固定截图框大小 不允许改变
canMove: true, // 上传图片是否可以移动
canMoveBox: true, // 截图框能否拖动
original: true, // 上传图片按照原始比例渲染
centerBox: false, // 截图框是否被限制在图片里面
high: false, // 是否按照设备的dpr输出等比例图片
infoTrue: true, // true为展示真实输出图片宽高false展示看到的截图框宽高
maximgSize: 800, // 限制图片最大宽度和高度
enlarge: 1, // 图片根据截图框输出比例倍数
mode: "contain" // 图片默认渲染方式(contain, cover, 100px, 100% auto)
},
preview: {},
imgName: "" // 图片名字
};
},
methods: {
open(data) {
console.log("🚀 ~ file: cropper.vue ~ line 93 ~ open ~ data", data)
this.imgName = data.name || "photo.png"
this.options.img = window.URL.createObjectURL(data);
this.dialogVisible = true;
},
close() {
this.dialogVisible = false;
},
// base64转图片文件
dataURLtoFile(dataurl, filename) {
let arr = dataurl.split(",");
let mime = arr[0].match(/:(.*?);/)[1];
let bstr = atob(arr[1]);
let len = bstr.length;
let u8arr = new Uint8Array(len);
while (len--) {
u8arr[len] = bstr.charCodeAt(len);
}
return new File([u8arr], filename, { type: mime });
},
// 左旋转
rotateLeft() {
this.$refs.cropper.rotateLeft();
},
// 右旋转
rotateRight() {
this.$refs.cropper.rotateRight();
},
// 放大缩小
changeScale(num) {
num = num || 1;
this.$refs.cropper.changeScale(num);
},
// 实时预览
previewImg(data) {
this.preview = data;
},
goUpload() {
this.$emit("upAgain");
},
// 上传图片
uploadImg() {
let self = this
if (self.loading) {
return
}
self.$emit("update:loading", true)
this.$refs.cropper.getCropData(data => {
let file = this.dataURLtoFile(data, this.imgName);
this.$emit("getFile", file)
});
}
}
};
</script>
<style lang="less" scoped>
.cropper_model_dlg {
/deep/ .el-dialog__body {
height: 500px !important;
.cropper_content {
width: 100%;
margin: 0 auto;
margin-top: 20px;
display: flex;
justify-content: space-between;
align-items: flex-start;
}
.cropper {
width: 400px;
height: 400px;
background: yellow;
}
.cropper_right {
width: 400px;
text-align: center;
}
.cropper_preview {
margin: 0 auto;
display: inline-block;
border: 1px solid #ddd;
}
.cropper_btns {
margin-top: 20px;
}
}
}
</style>
此代码并非最优,可根据实际情况更改及优化