|
<!--
* @Author: Devin
* @Date: 2023-02-20 14:24:02
* @LastEditors: Devin
* @LastEditTime: 2023-02-22 14:51:21
* @Description: 上传公共组件
-->
<template>
<div
class="__common-upload"
:class="fileType === 'image' ? '__common-upload-row' : ''"
>
<el-upload ref="uploadRef" v-model="fileList" v-bind="uploadAttr">
<!-- 图片 -->
<template v-if="fileType === 'image'">
<div class="__common-image-add">
<el-icon :size="20"><Plus /></el-icon>
<span class="__common-label">{{ uploadLabel }}</span>
</div>
</template>
<template v-else-if="fileType === 'file'">
<div class="__common-file-upload">
<el-button>
<common-icon
name="common-yunduanshangchuan"
:size="18"
></common-icon>
<span style="margin-left: 5px">{{ uploadLabel }}</span>
</el-button>
</div>
</template>
<template v-if="fileType === 'file'" #tip>
<div class="__common-upload-tip">
{{ fileTip }}
</div>
</template>
</el-upload>
<!-- 图片列表 -->
<template v-if="fileType === 'image'">
<div class="__common-image-list">
<el-image
v-for="(file, index) in fileList"
:key="index"
class="__common-image"
:src="file['url']"
></el-image>
</div>
</template>
<template v-else-if="fileType === 'file'">
<div class="__common-file-list">
<p
v-for="(file, index) in fileList"
:key="index"
class="__common-file-item"
@mouseenter="() => (curIndex = index)"
@mouseleave="() => (curIndex = -1)"
>
<span class="__common-file-title">
<common-icon
class="__common-icon"
name="common-dingwei"
:size="16"
></common-icon>
<span>{{ file.name }}</span>
</span>
<span
v-show="curIndex === index"
class="danger"
@click.stop="deleteFile(index)"
>
删除
</span>
</p>
</div>
</template>
</div>
</template>
<script setup lang="ts">
import { Plus } from '@element-plus/icons-vue';
import { ref, defineExpose } from 'vue';
/**
* @Author: Devin
* @Date: 2023-02-20 14:58:30
* @LastEditors: Devin
* @LastEditTime: Date
* @Description:
* 1. 支持文件上传:
* 1)文件大小限制,并toast提示;
* 2)文件类型限制,并toast提示,从选择文件位置及选择完后上传时文件类型确认,防止通过别路径上传时卡bug;
* 3)文件条数限制
* 2. 图片上传::
* 1) 大小限制
* 2)图片类型限制
* 3)图片回显
* 4)图片张数限制
*/
defineProps({
fileType: {
type: String,
default: () => 'file' // image/ file
},
// el-upload 原本属性
uploadAttr: {
type: Object,
default: () => {}
},
uploadLabel: {
type: String,
default: () => '上传图片' // image/ file
},
fileTip: {
type: String,
default: () => '只能上传 jpg/png 文件,且不超过 500kb' // image/ file
}
});
const fileList = ref<any>([
{
name: 'food.jpeg',
url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'
},
{
name: 'plant-1.png',
url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'
},
{
name: 'food.jpeg',
url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'
},
{
name: 'plant-2.png',
url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'
}
]);
// 当前选中条数
const curIndex = ref<any>(-1);
// 删除文件
function deleteFile(index: any) {
fileList.value.splice(index, 1);
}
const uploadRef = ref<any>(null);
defineExpose({
uploadRef
});
</script>
<script lang="ts">
export default {
name: 'CommonUpload'
};
</script>
<style scoped lang="scss">
.__common-upload {
.__common-image-add {
background: #ffffff;
border: 1px dashed #ebebeb;
border-radius: 4px;
width: 80px;
height: 80px;
color: #455a74;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.__common-label {
margin-top: 4px;
}
}
.__common-image-list {
display: flex;
.__common-image {
width: 80px;
height: 80px;
margin-left: 12px;
border-radius: 4px;
}
}
}
.__common-upload-row {
display: flex;
}
.__common-upload-tip {
color: #7b93a7;
font-size: 12px;
margin-top: 8px;
width: 100%;
}
.__common-file-item {
display: flex;
justify-content: space-between;
line-height: 32px;
cursor: pointer;
max-width: 300px;
.__common-file-title {
display: flex;
align-items: center;
color: #2d3e53;
.__common-icon {
margin-right: 10px;
}
}
}
.danger {
color: #ff5f5f;
}
</style>
|