You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
207 lines
5.5 KiB
207 lines
5.5 KiB
<template>
|
|
<div class="upload-wrapper">
|
|
<!-- 预览图片 -->
|
|
<div class="image-list" v-if="previewList.length>0">
|
|
<div class="image-box"
|
|
v-for="(item, index) in previewList" :key="index">
|
|
<img :src="item.url" class="image-preview" />
|
|
<!-- <i class="el-icon-close delete-icon" @click.stop="removeImage(index)" />-->
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 上传按钮 -->
|
|
<el-upload
|
|
class="image-uploader"
|
|
action=""
|
|
:http-request="uploadHandler"
|
|
:show-file-list="false"
|
|
:before-upload="beforeUpload"
|
|
:accept="acceptMime"
|
|
>
|
|
<GuipButton class="upload-button" type="ignore" :btnstyle="btnStyle">
|
|
<div class="bgImg"></div>
|
|
<span>选择图片</span>
|
|
</GuipButton>
|
|
</el-upload>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import GuipButton from "@/components/GuipButton.vue";
|
|
|
|
export default {
|
|
name: "ImgUpload",
|
|
components: {GuipButton},
|
|
props: {
|
|
value: {
|
|
type: [Array, File, null],
|
|
default: () => []
|
|
},
|
|
defaultUrls: {
|
|
type: Array,
|
|
default: () => []
|
|
},
|
|
acceptTypes: {
|
|
type: Array,
|
|
default: () => ['jpg', 'png']
|
|
},
|
|
sizeLimit: {
|
|
type: Number,
|
|
default: 2 // MB
|
|
},
|
|
btnStyle:{
|
|
type: Object,
|
|
default() {
|
|
return {
|
|
width: '118px',
|
|
color: '#23242B',
|
|
border: '1px solid #BABDC2',
|
|
background: '#F2F3F5',
|
|
'border-radius': '4px'
|
|
};
|
|
}
|
|
},
|
|
maxCount: {
|
|
type: Number,
|
|
default: 1
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
previewList: [],
|
|
initialized: false
|
|
};
|
|
},
|
|
watch: {
|
|
defaultUrls(newUrls) {
|
|
if (!this.initialized && Array.isArray(newUrls) && newUrls.length) {
|
|
this.previewList = newUrls
|
|
.filter(url => !!url)
|
|
.map(url => ({ url }));
|
|
this.initialized = true;
|
|
}
|
|
}
|
|
},
|
|
computed: {
|
|
// 根据后缀数组生成 MIME 类型字符串,用于 <el-upload accept="">
|
|
acceptMime() {
|
|
const map = {
|
|
jpg: 'image/jpeg',
|
|
jpeg: 'image/jpeg',
|
|
png: 'image/png',
|
|
webp: 'image/webp',
|
|
gif: 'image/gif'
|
|
};
|
|
return this.acceptTypes
|
|
.map(ext => map[ext.toLowerCase()])
|
|
.filter(Boolean)
|
|
.join(',');
|
|
}
|
|
},
|
|
methods: {
|
|
beforeUpload(file) {
|
|
if(this.maxCount === 1){
|
|
this.previewList = []
|
|
}
|
|
|
|
if (this.previewList.length >= this.maxCount) {
|
|
this.$message.warning(`最多只能上传 ${this.maxCount} 张图片`);
|
|
return false;
|
|
}
|
|
|
|
const isImage = file.type.startsWith("image/");
|
|
const isLt2M = file.size / 1024 / 1024 < 2;
|
|
if (!isImage) {
|
|
this.$message.error("只能上传图片格式!");
|
|
return false;
|
|
}
|
|
if (!isLt2M) {
|
|
this.$message.error("图片大小不能超过 2MB!");
|
|
return false;
|
|
}
|
|
|
|
const allowedTypes = this.acceptMime.split(',');
|
|
if (!allowedTypes.includes(file.type)) {
|
|
this.$message.error(`只允许上传 ${this.acceptTypes.join('/').toUpperCase()} 格式图片!`);
|
|
return false;
|
|
}
|
|
|
|
const url = URL.createObjectURL(file);
|
|
|
|
if(this.maxCount === 1){
|
|
this.previewList = [{ file, url }];
|
|
this.$emit('input', { file, url });
|
|
} else {
|
|
this.previewList.push({ file, url });
|
|
|
|
const files = this.previewList
|
|
.filter(item => item.file)
|
|
.map(item => item.file);
|
|
this.$emit('input', files);
|
|
}
|
|
|
|
return false;
|
|
},
|
|
uploadHandler() {
|
|
// 留空,使用自定义上传逻辑,由父组件决定是否提交 file 到服务器
|
|
},
|
|
removeImage(index) {
|
|
this.previewList.splice(index, 1);
|
|
const files = this.previewList
|
|
.filter(item => item.file)
|
|
.map(item => item.file);
|
|
this.$emit('input', files);
|
|
}
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<style scoped>
|
|
.upload-wrapper {
|
|
}
|
|
|
|
.image-list {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 8px;
|
|
margin-bottom: 10px;
|
|
}
|
|
.image-box {
|
|
position: relative;
|
|
width: 100px;
|
|
height: 100px;
|
|
}
|
|
.image-preview {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: cover;
|
|
border: 1px solid #ccc;
|
|
border-radius: 4px;
|
|
}
|
|
.delete-icon {
|
|
position: absolute;
|
|
top: -6px;
|
|
right: -6px;
|
|
font-size: 16px;
|
|
color: white;
|
|
background: #f56c6c;
|
|
border-radius: 50%;
|
|
padding: 2px;
|
|
cursor: pointer;
|
|
}
|
|
.bgImg{
|
|
width: 20px;
|
|
height: 16px;
|
|
margin-right: 6px;
|
|
background-image: url(@/assets/site/uploadIcon.svg);
|
|
}
|
|
.upload-button:hover{
|
|
border: 1px solid #006AFF!important;
|
|
}
|
|
.upload-button:hover .bgImg {
|
|
background-image: url(@/assets/site/uploadIcon_light.svg);
|
|
}
|
|
.upload-button:hover span {
|
|
color: #006AFF;
|
|
}
|
|
</style>
|
|
|