vite+vue项目之后台系统实现双文件上传并封装组件

309 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 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项目的后台系统中实现双文件上传并封装组件的所有代码和说明。