之前在使用vue-cropper 的时候,搜了一下资料基本都是照搬。要么不符合自己的需求,要么就是无法正常运行,要么就是无法复制,非常不符合我们搬运工的气质。于是就参考网上大佬的文章进行了修改,可以正常使用。希望对需要的同学有帮助。
首先安装vue-cropper
cnpm install vue-cropper --save
我使用的是ant-vue。下面贴出代码.
html 部分
<template>
<a-modal
title="图像剪裁"
:visible="visible"
:mask-closable="false"
:confirm-loading="confirmLoading"
:width="700"
:footer="null"
@cancel="cancelHandel">
<a-row>
<a-col :xs="24" :md="12" :style="{ height: '350px' }">
<vueCropper
ref="cropperRef"
:img="options.img"
:info="true"
:infoTrue="options.infoTrue"
:auto-crop="options.autoCrop"
:fixed-box="options.fixedBox"
:fixedNumber="options.fixedNumber"
:fixed="options.fixed"
:centerBox="options.centerBox"
@realTime="realTime"
>
</vueCropper>
</a-col>
<a-col :xs="24" :md="12" :style="{ height: '350px' }">
<div style="margin-left:10px;margin-bottom: 10px;">图片预览:</div>
<div :style="previews.div" style="margin:auto">
<!-- <img :src="previews.url" :style="previews.img" /> -->
<div v-html="previews.html" ></div>
</div>
</a-col>
</a-row>
<a-row :gutter="24" style="margin-top: 20px;">
<a-col :span="4" style="margin-right: 20px;">
<a-upload
name="file"
accept="image/*"
:before-upload="beforeUpload"
:show-upload-list="false">
<a-button type="primary">选择图片</a-button>
</a-upload>
</a-col>
<a-col :span="3">
<a-button type="primary" @click="refreshCrop" >复位</a-button>
</a-col>
<a-col :span="3" :offset="13">
<a-button type="primary" @click="finish('blob')">保存</a-button>
</a-col>
</a-row>
</a-modal>
</template>
script部分代码
<script lang="ts">
import { defineComponent, reactive, Ref, ref, toRefs, UnwrapNestedRefs, watch } from 'vue'
import VueCropper from "vue-cropper/src/vue-cropper.vue"
//import VueCropper from "vue-cropper" 注意不要使用这个
interface Options{
img:string | ArrayBuffer | null // 裁剪图片的地址
info: true, // 裁剪框的大小信息
outputSize:number, // 裁剪生成图片的质量 [1至0.1]
outputType: 'jpeg', // 裁剪生成图片的格式
canScale: boolean, // 图片是否允许滚轮缩放
autoCrop: boolean, // 是否默认生成截图框
autoCropWidth:number // 默认生成截图框宽度
autoCropHeight:number // 默认生成截图框高度
fixedBox:boolean // 固定截图框大小 不允许改变
fixed: boolean, // 是否开启截图框宽高固定比例
fixedNumber: Array<number>, // 截图框的宽高比例 需要配合centerBox一起使用才能生效
full: boolean, // 是否输出原图比例的截图
canMoveBox: boolean, // 截图框能否拖动
original: boolean, // 上传图片按照原始比例渲染
centerBox: boolean, // 截图框是否被限制在图片里面
infoTrue: boolean // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
}
export default defineComponent({
components:{
VueCropper
},
props:{
imgPath:{
type:String,
default:""
}
},
setup(props,{expose,emit}) {
const {imgPath} = toRefs(props)
const options:UnwrapNestedRefs<Options> = reactive({
img: '', // 需要剪裁的图片
autoCrop: true, // 是否默认生成截图框
autoCropWidth: 150, // 默认生成截图框的宽度
autoCropHeight: 150, // 默认生成截图框的长度
fixedBox: false, // 是否固定截图框的大小 不允许改变
info: true, // 裁剪框的大小信息
outputSize: 0.5, // 裁剪生成图片的质量 [1至0.1]
outputType: 'jpeg', // 裁剪生成图片的格式
canScale: false, // 图片是否允许滚轮缩放
fixed: true, // 是否开启截图框宽高固定比例
fixedNumber: [5, 4], // 截图框的宽高比例 需要配合centerBox一起使用才能生效
full: true, // 是否输出原图比例的截图
canMoveBox: false, // 截图框能否拖动
original: false, // 上传图片按照原始比例渲染
centerBox: true, // 截图框是否被限制在图片里面
infoTrue: true, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
})
const previews:Ref<any> = ref({})
const visible = ref(false)
const confirmLoading = ref(false)
const cropperRef:Ref<any> = ref(null)
if(imgPath.value){
options.img = imgPath.value
}
watch(imgPath,()=>{
if(imgPath.value){
options.img = imgPath.value
}
})
expose({
showModal(){
show()
}
})
const show= ()=> {
visible.value = true
}
const close= () => {
visible.value = false
}
const cancelHandel = () => {
close()
}
const beforeUpload = (file) => {
const reader = new FileReader()
// 转化为base64
reader.readAsDataURL(file)
reader.onload = () => {
// 获取到需要剪裁的图片 展示到剪裁框中
options.img = reader.result
}
return false
}
const refreshCrop = () => {
cropperRef.value.refresh()
}
// 上传图片(点击保存按钮)
const finish = (type) => {
console.log(cropperRef.value)
cropperRef.value.getCropData((data) => {
visible.value = false
console.log(data)
// data为base64图片,供接口使用
emit('saveResult', data)
})
}
// 裁剪之后的数据
const realTime = (data) => {
previews.value = data
}
return {
visible,confirmLoading,options,previews,cropperRef,
finish,beforeUpload,rotateLeft,rotateRight,changeScale,
cancelHandel,realTime,refreshCrop
}
},
})
</script>