开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第27天,点击查看活动详情
写在前面
上篇文章介绍了如何在vite+vue项目中实现单文件上传并封装组件,在本篇文章中介绍如何在vite+vue项目的后台系统中实现双文件上传并封装组件。
单文件上传
在src\components\UploadFile2.vue文件中封装双文件上传,相较于单文件上传,双文件上传需要用到el-upload的multiple属性,其中beforeRemove删除前的方法,handleRemove删除方法,handlePreview查看方法和单文件上传一样,差别在传的那个文件上:在单文件上传中我们定义一个new FormData(),并将选择的文件插入进去form.append("file", param.file);在双文件上传中我们定义一个forms,如果forms存在,我们直接往里面append文件,如果不存在,我们先给forms赋值forms = new FormData();再将文件插入进去,因为handleHttpRequest方法对选择的每个文件都会响应,所以我们只在第一次触发handleHttpRequest方法的时候调用上传文件的接口,同时给一个setTimeout,使上传文件的接口在所有文件都插入forms后才被调用,最后对返回值也做一些处理,我们的双文件上传就实现了
<template>
<el-upload :file-list="fileList" action="action" :on-preview="handlePreview" :on-remove="handleRemove"
:before-remove="beforeRemove" :http-request="handleHttpRequest" multiple
accept="jpg, jpeg, png, gif, webp, bmp, txt, pdf, xlsx ,xls ,doc, docx, zip ,rar, ppt, pptx, mp3">
<el-button type="primary">点击上传</el-button>
<template #tip>
<div class="el-upload__tip">
请上传不超过100M的文件
</div>
</template>
</el-upload>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import type { UploadProps, UploadUserFile } from 'element-plus'
import { FileUpload } from '@/api/UploadFile'
let fileList = ref<UploadUserFile[]>([
{
name: 'element-plus-logo.svg',
url: 'https://element-plus.org/images/element-plus-logo.svg',
},
])
let forms: any = null
const handleRemove: UploadProps['onRemove'] = (file, uploadFiles) => {
fileList.value = uploadFiles;
}
const handlePreview: UploadProps['onPreview'] = (uploadFile) => {
const el = document.createElement("a");
el.style.display = "none";
el.target = "_blank";
el.download = uploadFile.name;
el.href = uploadFile.url || '';
document.body.appendChild(el);
el.click();
document.body.removeChild(el);
}
const beforeRemove: UploadProps['beforeRemove'] = (uploadFile, uploadFiles) => {
return ElMessageBox.confirm(
`确定删除文件:${uploadFile.name}?`, 'Warning',
).then(
() => {
ElMessage({
type: 'success',
message: '删除成功!',
})
return true
},
() => false
)
}
// @ts-ignore
const handleHttpRequest: UploadProps['httpRequest'] = (param) => {
if (param.file.size > 100 * 1024 * 1024) {
return ElMessage.error('文件过大!请上传不超过100M的文件')
}
if (forms) {
forms.append("files", param.file); // 此处files需要根据后端需要的字段来命名
} else {
forms = new FormData();
forms.append("files", param.file);
setTimeout(() => {
// 模拟接口
setTimeout(() => {
// 模拟返回值
let res = [
{ fileName: '后端返回的文件名', url: '后端返回的文件url' }
]
res.forEach(el => {
let obj = {
name: el.fileName,
fileId: el.url,
...param,
};
param.onSuccess(obj);
let files = fileList.value;
files.push(obj);
fileList.value = files;
})
ElMessage({
message: '上传成功!',
type: 'success',
})
}, 1000)
// 真实后端用以下接口
// FileUpload(form).then(res => {
// console.log(res)
// ElMessage({
// message: '上传成功!',
// type: 'success',
// })
// })
});
}
}
</script>
写在最后
以上就是在vite+vue项目的后台系统中实现双文件上传并封装组件的所有代码和说明。