136 lines
3.3 KiB
Vue
136 lines
3.3 KiB
Vue
<template>
|
||
<el-upload ref="upload" :file-list="fileList" class="upload-demo" :limit="props.limit" :auto-upload="false" :on-change="fileChange">
|
||
<el-button type="primary" :disabled="fileList.length == 5">点击上传</el-button>
|
||
<template #tip>
|
||
<div v-if="props.format.length" class="el-upload__tip">只能上传{{ props.format.join() }} 文件,且不超过20MB</div>
|
||
</template>
|
||
<template #file="{ file }">
|
||
<section class="file_line">
|
||
<span class="name_">{{ file.name }}</span>
|
||
<el-icon v-if="props.type == 'view'" @click="handleDown(file)"><Download /></el-icon>
|
||
<el-icon v-else @click="handleDelFile(file)"><Close /></el-icon>
|
||
</section>
|
||
</template>
|
||
</el-upload>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, watch, nextTick } from 'vue';
|
||
import { ElMessage } from 'element-plus';
|
||
import { CommonUpload } from '@/apis';
|
||
|
||
const emit = defineEmits(['update:attrs']);
|
||
const props = defineProps({
|
||
attrs: {
|
||
type: Array,
|
||
default: () => [],
|
||
},
|
||
limit: {
|
||
type: Number,
|
||
default: 5,
|
||
},
|
||
format: {
|
||
type: Array,
|
||
default: () => [],
|
||
},
|
||
size: {
|
||
type: Number,
|
||
default: 20,
|
||
},
|
||
type: {
|
||
type: String,
|
||
default: 'view',
|
||
},
|
||
});
|
||
|
||
/* --------------- data --------------- */
|
||
// #region
|
||
const upload = ref();
|
||
const fileList = ref([]);
|
||
watch(
|
||
() => props.attrs,
|
||
(val) => {
|
||
fileList.value = val;
|
||
},
|
||
{ deep: true, immediate: true }
|
||
);
|
||
// #endregion
|
||
|
||
/* --------------- methods --------------- */
|
||
// #region
|
||
|
||
async function fileChange(file, list) {
|
||
let formatReg = true;
|
||
if (props.format.length > 0) {
|
||
formatReg = props.format.includes(file.name.slice(file.name.lastIndexOf('.') + 1));
|
||
}
|
||
const fileSize = file.size / 1024 / 1024 < props.size;
|
||
if (!formatReg) {
|
||
ElMessage.error(`上传文件格式不正确,仅支持${props.format.join('/ ')}格式`);
|
||
delAttr(file.uid, list);
|
||
}
|
||
if (!fileSize) {
|
||
ElMessage.error(`上传文件大小不能超过${props.size}MB`);
|
||
delAttr(file.uid, list);
|
||
}
|
||
await rowUploadPicture(file);
|
||
}
|
||
function handleDelFile(file) {
|
||
delAttr(file.uid, fileList.value);
|
||
}
|
||
function delAttr(uid, list = []) {
|
||
if (!uid || !list) return false;
|
||
let i = list.findIndex((v) => v.uid == uid);
|
||
if (i < 0) return;
|
||
else list.splice(i, 1);
|
||
nextTick(() => {
|
||
fileList.value = JSON.parse(JSON.stringify(list));
|
||
emit('update:attrs', fileList.value);
|
||
});
|
||
}
|
||
|
||
async function rowUploadPicture({ raw, name, uid }) {
|
||
const formData = new FormData();
|
||
formData.append('file', raw);
|
||
const res = await CommonUpload(formData);
|
||
if (res.code === 200) {
|
||
fileList.value.push({
|
||
name,
|
||
url: res.data.url,
|
||
status: 'success',
|
||
uid,
|
||
});
|
||
emit('update:attrs', fileList.value);
|
||
}
|
||
}
|
||
async function handleDown(file) {
|
||
let res = await fetch(file.url);
|
||
let blob = await res.blob();
|
||
let link = window.URL.createObjectURL(blob);
|
||
let a = document.createElement('a');
|
||
a.download = file.name;
|
||
a.href = link;
|
||
document.body.appendChild(a);
|
||
a.click();
|
||
document.body.removeChild(a);
|
||
}
|
||
// #endregion
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.file_line {
|
||
padding: 0 12px;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
.name_ {
|
||
flex: 1;
|
||
margin-right: 24px;
|
||
}
|
||
.el-icon {
|
||
font-size: 16px;
|
||
cursor: pointer;
|
||
}
|
||
}
|
||
</style>
|