npm install vue-cropper
yarn add vue-cropper
代码如下:
<template>
<el-dialog
title="图片裁剪"
:visible.sync="dialogVisible"
width="800px"
append-to-body
>
<div :key="dialogVisible" class="upload">
<div style="display: flex; justify-content: center">
<div class="eleme">
<el-upload
ref="upload"
class="upload-demo"
action=""
:before-upload="beforeUpload"
:on-preview="handlePreview"
:on-remove="handleRemove"
:auto-upload="true"
:show-file-list="false"
>
<el-button
slot="trigger"
icon="el-icon-picture-outline"
size="small"
type="warning"
>
选择图片
</el-button>
<!-- <div slot="tip" class="el-upload__tip">
只能上传jpg/png文件,且不超过500kb
</div> -->
</el-upload>
</div>
<div>
<el-button
style="margin-left: 20px"
size="small"
plain
icon="el-icon-refresh-right"
@click="rotateRight"
>右旋转</el-button>
<el-button
plain
size="small"
icon="el-icon-refresh-left"
@click="rotateLeft"
>左旋转</el-button>
<el-button
size="small"
plain
icon="el-icon-plus"
@click="changeScale(1)"
>放大</el-button>
<el-button
size="small"
icon="el-icon-minus"
plain
@click="changeScale(-1)"
>缩小</el-button>
<el-button
style="margin-left: 20px"
size="small"
type="success"
icon="el-icon-s-platform"
@click="submitUploadHandler"
>上传至素材库</el-button>
</div>
</div>
<div class="cropper" style="margin-top: 20px">
<div class="cropper-content">
<!-- 左侧裁剪视图 -->
<div class="cropper">
<vueCropper
ref="cropper"
:img="option.img"
:output-size="option.size"
:output-type="option.outputType"
:info="true"
:full="option.full"
:can-move="option.canMove"
:can-move-box="option.canMoveBox"
:original="option.original"
:auto-crop="option.autoCrop"
:auto-crop-width="option.autoCropWidth"
:auto-crop-height="option.autoCropHeight"
:fixed-box="option.fixedBox"
@realTime="realTime"
@imgLoad="imgLoad"
/>
</div>
<!-- 右侧 -->
<!-- <div style="margin-left: 20px">
<div
class="show-preview"
:style="{
width: '150px',
height: '155px',
overflow: 'hidden',
margin: '5px',
}"
>
<div :style="previews.div" class="preview">
<img :src="previews.url" :style="previews.img">
</div>
</div>
</div> -->
</div>
</div>
</div>
</el-dialog>
</template>
<script>
import { api_upImg } from '@/api/systemSetting'
import { attachmentApi } from '@/api/categoryApi'
import { VueCropper } from 'vue-cropper'
export default {
components: {
VueCropper
},
data() {
return {
dialogVisible: false,
// 剪切图片上传
previews: {},
option: {
img: '', // 预览图
outputSize: 1, // 剪切后的图片质量(0.1-1)
full: false, // 输出原图比例截图 props名full
outputType: 'png',
canMove: true,
original: false,
canMoveBox: true,
autoCrop: true,
autoCropWidth: 150,
autoCropHeight: 150,
fixedBox: true
},
fileName: '', // 本机文件地址
downImg: '#'
}
},
methods: {
openHandler() {
this.dialogVisible = true
},
closeHandler() {
this.dialogVisible = false
this.option.img = null
this.previews = {}
},
// 上传
submitUploadHandler(file) {
// this.$refs.upload.submit();
this.finish('blob')
},
handleRemove(file, fileList) {
// console.log(file, fileList);
},
handlePreview(file) {
// console.log(file);
// let data = window.URL.createObjectURL(new Blob([file]));
// this.option.img = data;
},
beforeUpload(file) {
const data = window.URL.createObjectURL(new Blob([file]))
this.fileName = file.name
this.option.img = data
},
// 放大/缩小
changeScale(num) {
num = num || 1
this.$refs.cropper.changeScale(num)
},
// 坐旋转
rotateLeft() {
this.$refs.cropper.rotateLeft()
},
// 右旋转
rotateRight() {
this.$refs.cropper.rotateRight()
},
// 上传图片(点击上传按钮)
async finish(type) {
const _this = this
const formData = new FormData() // 上传图片的格式 formdata格式
// 输出
if (type === 'blob') {
_this.$refs.cropper.getCropBlob(async(data) => {
console.log(data, 'datassssssss')
// const img = window.URL.createObjectURL(data)
formData.append('file', data, this.fileName)
formData.append('relationName', 'wx_category_files')
//文件上传接
const imgResult = await api_upImg(formData, {
contentType: false,
processData: false,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
})
// oss成功后添加到素材库
if (imgResult.data.code === 200) {
const resourceRes = await attachmentApi({
sattDir: imgResult.data.data.fileUrl,
pid: 0,
attType: imgResult.data.data.fileSuffix
})
if (resourceRes.data.code === 200) {
this.$message.success(resourceRes.data.msg)
this.closeHandler()
this.$emit('successFile')
}
}
})
} else {
this.$refs.cropper.getCropData((data) => {})
}
},
// 实时预览函数
realTime(data) {
// console.log("realTime");
this.previews = data
},
imgLoad(msg) {}
}
}
</script>
<style lang="scss" scoped>
.personalCenter-box {
height: 100%;
background-color: #eeecec;
.el-page-header {
height: 60px;
line-height: 60px;
background-color: #636268;
font-size: 20px;
color: #fff;
::v-deep .el-page-header__content {
color: #fff;
}
}
.content {
min-height: 600px;
width: 60%;
background-color: #fff;
margin: 20px auto 0px;
display: flex;
padding: 20px;
.left {
flex: 0 0 200px;
}
.right {
flex: 1;
}
}
}
.cropper-content {
width: 100%;
display: flex;
}
.cropper {
width: 300px;
height: 300px;
margin: 0 auto;
}
.show-preview {
flex: 1;
-webkit-flex: 1;
display: flex;
display: -webkit-flex;
justify-content: center;
-webkit-justify-content: center;
}
.preview {
overflow: hidden;
border-radius: 50%;
border: 1px solid #cccccc;
background: #cccccc;
margin-left: 40px;
}
.cropper-content .show-preview .preview {
margin-left: 0;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
user-select: none;
}
</style>