单文件上传没有什么好说的,只是因为element官网没有具体的例子,所以需要自己稍微画一个div
全部代码如下:
<!-- 图片上传组件:用于船籍新增按钮,选择国旗 -->
<template>
<div class="container">
<!-- 缩略图显示-->
<div class="img-show" v-if="imgUrl">
<img :src="imgUrl" class="avatar" />
<span class="actions">
<!-- 删除 -->
<span class="item">
<el-icon @click="handleDel()"><Delete /></el-icon>
</span>
</span>
</div>
<!-- 图片上传 -->
<el-upload
v-else
action="#"
class="uploader-avatar"
list-type="picture"
:auto-upload="false"
:show-file-list="false"
:on-change="handleUpload"
>
<el-icon><Plus /></el-icon>
</el-upload>
</div>
</template>
<script lang="ts" setup name="upload-image">
import { ref, watch } from "vue";
import { Plus, Delete } from "@element-plus/icons-vue";
import { ElMessage } from "element-plus";
const emit = defineEmits(["update:modelValue"]);
const props = defineProps({
base64: String,
});
const imgUrl = ref();
//监听父组件是否传递base64数据过来,从而判断是新增还是修改
watch(
props,
newQuestion => {
imgUrl.value = newQuestion.base64;
},
{ immediate: true }
);
//将图片的data返回给父组件registry.vue
const handleUpload = (file: any) => {
// 检查图片类型是否为 jpg 或 png
const isJpgOrPng =
file.raw.type === "image/jpeg" || file.type === "image/png";
if (!isJpgOrPng) {
// 如果不是 jpg 或 png,则提示用户
const errorMsg = "图片类型只能为jpg/png";
ElMessage.error(errorMsg);
} else {
const reader = new FileReader();
reader.readAsDataURL(file.raw);
reader.onload = () => {
imgUrl.value = reader.result as any;
// 触发自定义事件,并将 Base64 编码传递给父组件
emit("update:modelValue", imgUrl.value);
};
}
};
//删除国旗
const handleDel = () => {
//清除组件上的国旗图片
imgUrl.value = "";
//清除传递给父组件的值
emit("update:modelValue", "");
};
</script>
<style scoped>
.container {
width: 124px;
height: 124px;
overflow: hidden;
}
.uploader-avatar :deep(.el-upload) {
background-color: #fbfdff;
border: 1px dashed #c0ccda;
border-radius: 6px;
box-sizing: border-box;
width: 124px;
height: 124px;
cursor: pointer;
line-height: 124px;
vertical-align: top;
overflow: hidden;
}
.img-show {
position: relative;
border: 1px solid #c0ccda;
border-radius: 6px;
box-sizing: border-box;
width: 124px;
height: 124px;
cursor: pointer;
overflow: hidden;
}
.uploader-avatar :deep(i) {
font-size: 28px;
color: #8c939d;
}
.avatar {
width: 100%;
height: 100%;
object-fit: contain;
}
.actions {
position: absolute;
width: 100%;
height: 100%;
line-height: 148px;
left: 0;
top: 0;
cursor: default;
text-align: center;
color: #fff;
opacity: 0;
font-size: 20px;
background-color: rgba(0, 0, 0, 0.5);
transition: opacity 0.3s;
}
.actions:hover {
opacity: 1;
}
.actions:hover span {
display: inline-block;
}
.actions span {
display: none;
margin: 0 16px;
cursor: pointer;
}
</style>