vue版本 v3.2.26;vue-cropper版本 v1.0.9
功能展示
完整代码
<template>
<div>
<div
class="avatar"
style="margin-left: 40px; position: relative; width: 137px; height: 137px"
>
<img
v-if="cropperOption.imageUrl"
style="width: 100%; height: 100%; border-radius: 50%; object-fit: cover"
:src="cropperOption.imageUrl"
alt=""
/>
<el-avatar v-else :size="137" style="">
<el-icon size="72"> <UserFilled /> </el-icon>
</el-avatar>
<div class="avatar_camera" @click="uploadAvatar()">
<el-icon size="25"><CameraFilled /></el-icon>
</div>
</div>
<MyDialog title="头像上传" top="5%" ref="myDialogRef" width="800">
<template #content>
<div style="width: 760px; height: 450px; display: flex">
<vueCropper
ref="cropperRef"
:img="cropperOption.img"
:output-size="cropperOption.size"
:output-type="cropperOption.outputType"
:info="true"
:full="cropperOption.full"
:can-move="cropperOption.canMove"
:can-move-box="cropperOption.canMoveBox"
:fixed-box="cropperOption.fixedBox"
:original="cropperOption.original"
:auto-crop="cropperOption.autoCrop"
:auto-crop-width="cropperOption.autoCropWidth"
:auto-crop-height="cropperOption.autoCropHeight"
:center-box="cropperOption.centerBox"
:high="cropperOption.high"
mode="contain"
:max-img-size="cropperOption.max"
></vueCropper>
</div>
<div style="margin-top: 20px; text-align: center">
<el-button
style="
width: 84px;
height: 32px;
color: #1a1a1a;
background: #f2f3f5;
"
:icon="Close"
@click="myDialogRef.hideDialog()"
>取 消</el-button
>
<el-button
style="width: 84px; height: 32px; color: #fff; background: #0256ff"
:icon="Position"
@click="handleCrapFinished"
>确认</el-button
>
</div>
</template>
</MyDialog>
</div>
</template>
<script setup>
// 头像上传
import 'vue-cropper/dist/index.css'
import { VueCropper } from 'vue-cropper'
import { UserFilled } from '@element-plus/icons-vue'
import { ref, getCurrentInstance, nextTick } from 'vue'
import { Close, Position } from '@element-plus/icons-vue'
import { uploadFile } from '@/api/common.js'
import { baseUrl } from '@/config/env'
const { proxy } = getCurrentInstance()
const cropperRef = ref('')
// const crap = ref(false)
const myDialogRef = ref('')
const cropperOption = ref({
img: '',
size: 1,
full: false,
outputType: 'png',
canMove: true,
fixedBox: false,
original: false,
canMoveBox: true,
autoCrop: true,
// 只有自动截图开启 宽度高度才生效
// autoCropWidth: 750,
// autoCropHeight: 340,
centerBox: true,
high: true,
max: 99999,
fileinfo: [],
imageUrl: '',
// imageUrl: new URL('../..//img/img1.jpg', import.meta.url).href, //裁剪后的url
})
let avatarObj = {}
// 上传头像
const uploadAvatar = () => {
proxy.$fileTypeLimit
.upload(true, '', '.gif,.jpeg,.png,.jpg,.svg,')
.then(file => {
// console.log('file', file)
cropperOption.value.img = getObjectURL(file[0])
// console.log('getObjectURL(file[0])', getObjectURL(file[0]), file[0])
cropperOption.value.fileinfo = file[0]
myDialogRef.value.showDialog()
nextTick(() => {
// console.log(34343434, cropperRef.value)
cropperRef.value.startCrop()
})
})
}
const handleCrapFinished = () => {
cropperRef.value.getCropBlob(data => {
// do something
let file = new File([data], cropperOption.value.fileinfo.name, {
type: cropperOption.value.fileinfo.type,
lastModified: Date.now(),
})
let formData = new FormData()
formData.append('file', file)
// 上传头像的接口
uploadFile(formData).then(res => {
avatarObj = {
...res.data.data,
}
cropperOption.value.imageUrl = baseUrl + res.data.data.url
// crap.value = false
myDialogRef.value.hideDialog()
})
})
}
const getObjectURL = f => {
if (!f) return
let url = null
if (window.createObjectURL != undefined) {
// basic
url = window.createObjectURL(f)
} else if (window.URL != undefined) {
// mozilla(firefox)
url = window.URL.createObjectURL(f)
} else if (window.webkitURL != undefined) {
// webkit or chrome
url = window.webkitURL.createObjectURL(f)
}
return url
}
const getAvatarObj = () => {
return avatarObj
}
const setImageUrl = (assignmentFile = {}) => {
if (!assignmentFile.url) return
cropperOption.value.imageUrl = `${baseUrl}${assignmentFile.url}`
avatarObj = {
...assignmentFile,
}
}
defineExpose({
getAvatarObj,
setImageUrl,
})
</script>
<style lang="scss" scoped>
.avatar_camera {
cursor: pointer;
position: absolute;
width: 48px;
height: 48px;
border: 2px solid #fff;
background: #e8f3ff;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
right: -5px;
bottom: -5px;
}
:deep(.el-avatar) {
overflow: visible;
}
</style>