图片裁剪
This commit is contained in:
parent
1b7d40d2cc
commit
77d12a249c
@ -2,19 +2,37 @@
|
|||||||
<div class="img-cropper" :class="{ 'img-cropper-auto': $slots.default, circled: circled }">
|
<div class="img-cropper" :class="{ 'img-cropper-auto': $slots.default, circled: circled }">
|
||||||
<slot name="default"></slot>
|
<slot name="default"></slot>
|
||||||
<template v-if="!$slots.default">
|
<template v-if="!$slots.default">
|
||||||
|
<template v-if="src">
|
||||||
|
<div class="img-cropper-img" @click="openCropper">
|
||||||
|
<img :src="src" :class="{ circled: circled }"/>
|
||||||
|
<div class="mask" :class="{ circled: circled }" @click.stop>
|
||||||
|
<div class="handle-icon" @click="openCropper">
|
||||||
|
<el-icon >
|
||||||
|
<Edit />
|
||||||
|
</el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="handle-icon" @click="viewImg">
|
||||||
|
<el-icon>
|
||||||
|
<ZoomIn />
|
||||||
|
</el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="handle-icon" @click="deleteImg">
|
||||||
|
<el-icon>
|
||||||
|
<Delete />
|
||||||
|
</el-icon>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
<div class="img-cropper-img" @click="openCropper">
|
<div class="img-cropper-img" @click="openCropper">
|
||||||
<img :src="src" :class="{ circled: circled }" v-if="src"/>
|
<div class="addImg">
|
||||||
<div class="addImg" v-else>
|
|
||||||
<el-icon>
|
<el-icon>
|
||||||
<plus />
|
<plus />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
</div>
|
</div>
|
||||||
<div class="mask" :class="{ circled: circled }">
|
|
||||||
<el-icon class="el-input__icon">
|
|
||||||
<UploadOutlined />
|
|
||||||
</el-icon>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</template>
|
||||||
</template>
|
</template>
|
||||||
<CropperModal
|
<CropperModal
|
||||||
ref="cropperRef"
|
ref="cropperRef"
|
||||||
@ -30,7 +48,6 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import CropperModal from './CropperModal.vue';
|
import CropperModal from './CropperModal.vue';
|
||||||
import { UploadOutlined } from '@vicons/antd';
|
|
||||||
import { cssUnit } from '@/utils';
|
import { cssUnit } from '@/utils';
|
||||||
|
|
||||||
const cropperRef = ref();
|
const cropperRef = ref();
|
||||||
@ -39,7 +56,7 @@
|
|||||||
title: { type: String, default: '图片上传' },
|
title: { type: String, default: '图片上传' },
|
||||||
src: { type: String, required: true },
|
src: { type: String, required: true },
|
||||||
circled: { type: Boolean, default: false },
|
circled: { type: Boolean, default: false },
|
||||||
width: { type: [String, Number], default: 200 },
|
width: { type: [String, Number], default: 150 },
|
||||||
uploadApi: {
|
uploadApi: {
|
||||||
type: Function as PropType<(params) => Promise<any>>,
|
type: Function as PropType<(params) => Promise<any>>,
|
||||||
},
|
},
|
||||||
@ -50,9 +67,15 @@
|
|||||||
const iconSize = cssUnit(Math.ceil(parseInt(getWidth) / 4));
|
const iconSize = cssUnit(Math.ceil(parseInt(getWidth) / 4));
|
||||||
|
|
||||||
const emit = defineEmits(['uploadSuccess']);
|
const emit = defineEmits(['uploadSuccess']);
|
||||||
function handleSuccess(value){
|
const viewImg =()=>{
|
||||||
emit('uploadSuccess',value)
|
window.open(props.src)
|
||||||
}
|
}
|
||||||
|
const deleteImg = () => {
|
||||||
|
emit('uploadSuccess', {fileUrl:''});
|
||||||
|
};
|
||||||
|
function handleSuccess(value){
|
||||||
|
emit('uploadSuccess',value)
|
||||||
|
}
|
||||||
function openCropper() {
|
function openCropper() {
|
||||||
cropperRef.value.showModal();
|
cropperRef.value.showModal();
|
||||||
}
|
}
|
||||||
@ -69,7 +92,7 @@ function handleSuccess(value){
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
&-img {
|
&-img {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -100,12 +123,20 @@ function handleSuccess(value){
|
|||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
padding: 0 6%;
|
||||||
transition: opacity 0.4s;
|
transition: opacity 0.4s;
|
||||||
|
.handle-icon {
|
||||||
.el-icon {
|
display: flex;
|
||||||
color: #fff;
|
flex-direction: column;
|
||||||
font-size: v-bind(iconSize);
|
align-items: center;
|
||||||
}
|
justify-content: center;
|
||||||
|
padding: 0 6%;
|
||||||
|
color: aliceblue;
|
||||||
|
.el-icon {
|
||||||
|
color: #fff;
|
||||||
|
font-size:20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<basicModal ref="modalRef" @register="modalRegister" @ok="handleOk">
|
<basicModal ref="modalRef" @register="modalRegister" @ok="handleOk" @close="handleClose">
|
||||||
<template #default>
|
<template #default>
|
||||||
<div class="cropper-box">
|
<div class="cropper-box">
|
||||||
<div class="cropper-box-left">
|
<div class="cropper-box-left">
|
||||||
@ -17,7 +17,7 @@
|
|||||||
<el-upload
|
<el-upload
|
||||||
:show-file-list="false"
|
:show-file-list="false"
|
||||||
accept="image/*"
|
accept="image/*"
|
||||||
action="http://www.mocky.io/v2/5e4bafc63100007100d8b70f"
|
:http-request="handleHttpUpload"
|
||||||
:before-upload="beforeUpload"
|
:before-upload="beforeUpload"
|
||||||
style="width: auto"
|
style="width: auto"
|
||||||
>
|
>
|
||||||
@ -212,7 +212,8 @@
|
|||||||
function showModal() {
|
function showModal() {
|
||||||
openModal();
|
openModal();
|
||||||
}
|
}
|
||||||
|
function handleHttpUpload(){
|
||||||
|
}
|
||||||
// 上传图片
|
// 上传图片
|
||||||
function beforeUpload(file) {
|
function beforeUpload(file) {
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
@ -265,6 +266,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
function handleClose(){
|
||||||
|
src.value =''
|
||||||
|
previewSource.value=''
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
src,
|
src,
|
||||||
@ -273,10 +278,12 @@
|
|||||||
previewSource,
|
previewSource,
|
||||||
showModal,
|
showModal,
|
||||||
beforeUpload,
|
beforeUpload,
|
||||||
|
handleHttpUpload,
|
||||||
handleCropend,
|
handleCropend,
|
||||||
handleReady,
|
handleReady,
|
||||||
handlerToolbar,
|
handlerToolbar,
|
||||||
handleOk,
|
handleOk,
|
||||||
|
handleClose
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -105,7 +105,7 @@
|
|||||||
v-model:image-url="formData.avatar">
|
v-model:image-url="formData.avatar">
|
||||||
<template v-slot:tip>支持扩展名: jpg png jpeg;文件大小不超过200M</template>
|
<template v-slot:tip>支持扩展名: jpg png jpeg;文件大小不超过200M</template>
|
||||||
</UploadImg> -->
|
</UploadImg> -->
|
||||||
<Cropper ref="cropperCircled" :src="formData.avatar" :uploadApi="upload" title="矩形头像上传" @uploadSuccess="uploadSuccess">
|
<Cropper ref="cropperCircled" :src="formData.avatar" :uploadApi="upload" title="头像上传" @uploadSuccess="uploadSuccess">
|
||||||
<template #avatar>
|
<template #avatar>
|
||||||
</template>
|
</template>
|
||||||
</Cropper>
|
</Cropper>
|
||||||
@ -193,6 +193,7 @@ const passwordConfirmValidator = (
|
|||||||
|
|
||||||
const uploadSuccess =(data)=>{
|
const uploadSuccess =(data)=>{
|
||||||
formData.avatar = data.fileUrl
|
formData.avatar = data.fileUrl
|
||||||
|
formRef.value?.validateField("avatar");
|
||||||
}
|
}
|
||||||
const dialogClose = () => {
|
const dialogClose = () => {
|
||||||
emit("update:visible", false);
|
emit("update:visible", false);
|
||||||
@ -250,10 +251,6 @@ const getAllDict = async () => {
|
|||||||
list = await getPositionAllList();
|
list = await getPositionAllList();
|
||||||
optionData.positionList = list ? list : [];
|
optionData.positionList = list ? list : [];
|
||||||
};
|
};
|
||||||
function cropperCircledImg() {
|
|
||||||
cropperCircled.value.openCropper();
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getAllDict()
|
getAllDict()
|
||||||
if (props.userId) {
|
if (props.userId) {
|
||||||
|
Loading…
Reference in New Issue
Block a user