update:图片上传组件优化

This commit is contained in:
2025-12-02 11:30:28 +08:00
parent 1bbbf529bf
commit 397d2150c9

View File

@@ -1,29 +1,46 @@
<template>
<div class="comp-content">
<div class="comp-content comp-upload-img" :class="{ 'text-mode': viewMode === 'text' }">
<div class="content">
<div v-if="imgUrl" class="preview">
<el-image class="img" :src="imgUrl" fit="cover" />
<div v-if="!disabled" class="cover">
<div class="icon-btns">
<el-icon :size="20" class="cover-icon"><View /></el-icon>
<el-icon :size="20" class="cover-icon" @click="delFun"><Delete /></el-icon>
<template v-if="imgUrl">
<div v-if="viewMode === 'card'" class="preview">
<el-image class="img" :src="imgUrl" fit="cover" />
<div class="cover">
<div class="icon-btns">
<el-icon :size="20" class="cover-icon" @click="previewFun"><View /></el-icon>
<el-icon v-if="!disabled" class="cover-icon" :size="20" @click="delFun">
<Delete />
</el-icon>
</div>
</div>
</div>
</div>
<div v-else class="upload">
<el-upload
:show-file-list="false"
:before-upload="beforeUploadFun"
>
<div v-if="!uploading" class="add">
<el-icon :size="20" class="add-icon"><Plus /></el-icon>
<div v-else>
<div class="icon-btns">
<el-icon :size="18" class="cover-icon add" @click="previewFun"><View /></el-icon>
<el-icon v-if="!disabled" class="cover-icon del" :size="18" @click="delFun">
<Delete />
</el-icon>
</div>
</div>
</template>
<div v-else class="upload">
<el-upload :show-file-list="false" accept="image/*" :before-upload="beforeUploadFun">
<template v-if="!uploading">
<div v-if="viewMode === 'card'" class="add-card">
<el-icon :size="20" class="add-icon add"><Plus /></el-icon>
</div>
<div v-else class="add-text del">点击上传图片</div>
</template>
<div v-else class="progress">
<el-progress type="circle" :percentage="percentage" :width="120" />
<el-progress
:type="viewMode === 'card' ? 'circle' : 'line'"
:percentage="percentage"
:width="120"
/>
</div>
</el-upload>
</div>
</div>
<FilePreview v-model="previewVisible" :fileId="fileId" />
</div>
</template>
@@ -32,15 +49,18 @@ import { ref, watch } from 'vue';
import { dataUploadAvatarApi } from '@/api/data/data';
import { Plus, View, Delete } from '@element-plus/icons-vue';
import { ElMessage } from 'element-plus';
import FilePreview from '@/components/common/filePreview/index.vue';
interface Props {
modelValue: any;
disabled?: boolean;
viewMode?: string;
}
const props = withDefaults(defineProps<Props>(), {
modelValue: '',
disabled: false,
viewMode: 'card', // card卡片模式 text文本模式
});
const emit = defineEmits(['update:modelValue', 'change']);
@@ -49,14 +69,20 @@ const env = import.meta.env;
const uploading = ref(false);
const percentage = ref(0);
const imgUrl = ref('');
const fileId = ref<any>('');
const previewVisible = ref(false);
watch(() => props.modelValue, (val: any) => {
if (val) {
imgUrl.value = `${env.VITE_API_IMAGE_PREVIEW_URL}/data/previewImage?fileId=${val}`;
} else {
imgUrl.value = '';
}
}, { deep: true, immediate: true });
watch(
() => props.modelValue,
(val: any) => {
if (val) {
imgUrl.value = `${env.VITE_API_IMAGE_PREVIEW_URL}/data/previewImage?fileId=${val}`;
} else {
imgUrl.value = '';
}
},
{ deep: true, immediate: true }
);
const beforeUploadFun = (file: any) => {
uploading.value = true;
@@ -67,20 +93,27 @@ const beforeUploadFun = (file: any) => {
const { loaded, total } = event;
const percent = (loaded / total) * 100;
percentage.value = Number(percent.toFixed(2));
}).then((res: any) => {
if (res.code === 200) {
const avatarId = res.data.avatarId;
updateFun(avatarId);
imgUrl.value = `${env.VITE_API_IMAGE_PREVIEW_URL}/data/previewImage?fileId=${avatarId}`;
ElMessage.success('上传成功');
}
}).finally(() => {
uploading.value = false;
percentage.value = 0;
});
})
.then((res: any) => {
if (res.code === 200) {
const avatarId = res.data.avatarId;
updateFun(avatarId);
imgUrl.value = `${env.VITE_API_IMAGE_PREVIEW_URL}/data/previewImage?fileId=${avatarId}`;
ElMessage.success('上传成功');
}
})
.finally(() => {
uploading.value = false;
percentage.value = 0;
});
return false;
};
const previewFun = () => {
fileId.value = props.modelValue;
previewVisible.value = true;
};
const delFun = () => {
imgUrl.value = '';
updateFun('');
@@ -93,15 +126,43 @@ const updateFun = (data: any) => {
</script>
<style lang="scss" scoped>
.comp-content {
.comp-upload-img {
width: 122px !important;
height: 122px !important;
&.text-mode {
width: auto !important;
height: 22px !important;
.content {
border: none;
.upload {
.add-text {
font-size: 12px;
color: var(--el-color-primary);
}
}
}
}
.content {
width: 100%;
height: 100%;
border: dashed 1px var(--el-border-color-light);
border-radius: var(--border-radius-normal);
overflow: hidden;
.icon-btns {
display: flex;
align-items: center;
width: 100%;
.cover-icon {
margin: 0 var(--margin-small);
cursor: pointer;
&.add {
color: var(--el-color-primary);
}
&.del {
color: var(--el-color-danger);
}
}
}
.preview {
width: 120px;
height: 120px;
@@ -128,20 +189,15 @@ const updateFun = (data: any) => {
height: 100%;
background-color: rgba(0, 0, 0, 0.6);
.icon-btns {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
.cover-icon {
color: #fff;
margin: 0 var(--margin-small);
cursor: pointer;
}
}
}
}
.upload {
.add {
.add-card {
width: 120px;
height: 120px;
display: flex;