refactor: ♻️ 重构图片上传,删除掉单图上传,一个图片上传支持多种情况

重构图片上传,删除掉单图上传,一个图片上传支持多种情况
This commit is contained in:
Theo
2024-12-25 11:40:14 +08:00
parent f4ba493fcd
commit a023b4b623
4 changed files with 400 additions and 478 deletions

View File

@@ -1,159 +0,0 @@
<!-- 单图上传组件 -->
<template>
<el-upload
v-model="imgUrl"
class="img-upload"
:show-file-list="false"
list-type="picture-card"
:before-upload="handleBeforeUpload"
:http-request="uploadFile"
:style="{ width: props.size, height: props.size }"
:accept="props.accept"
>
<template #default>
<el-image v-if="imgUrl" :src="imgUrl" />
<div v-if="imgUrl" class="img-upload__overlay">
<el-icon class="img-upload__preview-icon" @click.stop="handlePreview">
<ZoomIn />
</el-icon>
<el-icon class="img-upload__delete-icon" @click.stop="handleDelete">
<Delete />
</el-icon>
</div>
<el-icon v-else class="img-upload__add-icon">
<Plus />
</el-icon>
</template>
</el-upload>
</template>
<script setup lang="ts">
import { ElImageViewer, UploadRawFile, UploadRequestOptions } from "element-plus";
import FileAPI from "@/api/file";
const props = defineProps({
modelValue: {
type: String,
default: "",
},
maxSize: {
type: Number,
default: 10, // 默认限制为 10MB
},
accept: {
type: String,
default: "",
},
size: {
type: String,
default: "150px",
},
});
const emit = defineEmits(["update:modelValue"]);
const imgUrl = defineModel("modelValue", {
type: String,
required: true,
default: "",
});
/**
* 自定义图片上传
*
* @param options
*/
async function uploadFile(options: UploadRequestOptions): Promise<any> {
const data = await FileAPI.upload(options.file);
imgUrl.value = data.url;
}
/**
* 限制用户上传文件的格式和大小
*/
function handleBeforeUpload(file: UploadRawFile) {
if (file.size > props.maxSize * 1024 * 1024) {
ElMessage.warning(`上传图片不能大于${props.maxSize}MB`);
return false;
}
return true;
}
/**
* 预览图片
*/
function handlePreview() {
if (imgUrl.value) {
const imageViewerApp = createApp({
setup() {
return () =>
h(ElImageViewer, {
urlList: [imgUrl.value],
initialIndex: 0,
onClose: () => {
imageViewerApp.unmount();
document.body.removeChild(container);
},
});
},
});
const container = document.createElement("div");
document.body.appendChild(container);
imageViewerApp.mount(container);
}
}
/**
* 删除图片
*/
function handleDelete() {
imgUrl.value = "";
}
</script>
<style scoped lang="scss">
:deep(.el-upload--picture-card) {
/* width: var(--el-upload-picture-card-size);
height: var(--el-upload-picture-card-size); */
width: 100%;
height: 100%;
}
.img-upload {
position: relative;
overflow: hidden;
cursor: pointer;
border: 1px var(--el-border-color) solid;
border-radius: 5px;
&:hover {
border-color: var(--el-color-primary);
}
&__delete-icon {
margin-left: 5px;
}
&__overlay {
position: absolute;
top: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
color: #fff;
background-color: var(--el-overlay-color-lighter);
border-radius: 6px;
opacity: 0;
transition: opacity var(--el-transition-duration);
&:hover {
opacity: 1;
}
}
}
</style>