136 lines
3.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>