自定义封装图片上传组件并自定上传细节
<template>
<label
class="admin-upload-oss"
:class="{
'admin-upload-oss-img-true': fileUrl,
}"
:form="'uploadID' + uploadID"
>
<img
v-if="fileUrl"
class="admin-upload-oss-img"
:src="fileUrl"
alt="fileUrl"
@error="handleError"
/>
<div v-else class="admin-upload-oss-text" :style="{ color: textColor }">
<el-icon><Plus /></el-icon>
<div class="up-text">点击上传</div>
<div class="triangle-up"></div>
</div>
<input
:id="'uploadID' + uploadID"
ref="uploadInput"
accept="image/png, image/jpeg, image/jpg"
class="hidden"
type="file"
@change="handleUpload"
/>
</label>
</template>
<script setup lang="ts">
import { fetchUploadFile } from '~/fetch/http'
import loginIcon from '@/assets/img/login/login-icon1.png'
import { ElMessage } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'
defineProps({
textColor: {
type: String,
default: '#2267c5',
},
})
const uploadID = (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1)
const loading = ref(false)
const uploadInput = ref()
const fileUrl = defineModel('fileUrl', {
type: String,
default: '',
})
const handleUpload = async (fileData: any) => {
try {
const file = fileData.target.files[0]
if (!file) {
return false
}
const txtName = '.jpg|.png|.jpeg'
const extName = file.name
.substring(file.name.lastIndexOf('.'))
.toLowerCase()
const extSize = file.size
if (!txtName.includes(extName)) {
ElMessage({
message: '请上传正确的文件格式!如:' + txtName,
type: 'error',
})
uploadInput.value.value = null
return false
}
if (extSize / 1000 / 1000 > 3) {
ElMessage({
message: '请上传小于 3M 的图片!',
type: 'error',
})
uploadInput.value.value = null
return false
}
if (!file) return false
loading.value = true
ElMessage({
message: '上传中',
type: 'success',
})
const formData = new FormData()
formData.append('bucket', 'BS')
formData.append('path', '/bs')
formData.append('type', 'image')
formData.append('importFile', file)
const { data } = await fetchUploadFile(formData)
ElMessage({
message: '上传成功',
type: 'success',
})
fileUrl.value = data.accessUrl
loading.value = false
} catch (error: any) {
ElMessage({
message: error.data?.msg || '上传失败',
type: 'error',
})
uploadInput.value.value = null
loading.value = false
}
}
const handleError = (event: any) => {
event.target.src = loginIcon
}
</script>
<style lang="scss">
// 上传头像 做上传图片展示限制以及上传失败结果处理显示
.admin-upload-oss {
display: block;
width: 177px;
height: 210px;
background: #ddf8f1;
border-radius: 6px;
border: 1px solid #c5e1d9;
position: relative;
cursor: pointer;
.admin-upload-oss-text {
position: relative;
color: #666666 !important;
.triangle-up {
position: absolute;
width: 0;
height: 0;
bottom: -20px;
z-index: 1;
border-left: 88px solid transparent;
border-right: 88px solid transparent;
border-bottom: 100px solid rgb(255, 255, 255);
}
.up-text {
position: absolute;
z-index: 2;
bottom: 30px;
left: 60px;
color: #15c298;
}
.el-icon {
font-size: 46px;
color: #15c298;
font-weight: 600;
position: absolute;
bottom: 85px;
left: 65px;
}
}
&:hover {
.admin-upload-oss-text {
opacity: 0.6;
}
}
&.admin-upload-oss-img-true {
&::before {
position: absolute;
content: '重新上传';
bottom: 10px;
left: 0;
width: 100%;
height: 30px;
z-index: 2;
text-align: center;
color: rgba(255, 255, 255, 0.6);
transition: all 0.3s;
opacity: 0;
}
&:hover {
&::before {
opacity: 1;
}
.admin-upload-oss-img {
opacity: 0.6;
}
}
}
// 提示问题
.admin-upload-oss-text {
position: absolute;
bottom: 21px;
width: 100%;
text-align: center;
transition: all 0.3s;
}
// 展示 img
.admin-upload-oss-img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 6px;
position: relative;
transition: all 0.3s;
}
.hidden {
visibility: hidden;
}
}
</style>