在现代Web开发中,文件上传功能是许多应用的核心需求之一。无论是企业管理系统、内容管理系统还是医疗信息系统,上传附件的功能都至关重要。本文将分享一个基于 Vue3 和 Element Plus 实现的文件上传组件,结合父子组件的协作,展示如何构建一个功能强大、用户体验友好的文件上传解决方案。以下是完整的代码实现和使用指南,适合前端开发者参考和复用。
为什么选择这个解决方案?
-
灵活性:支持多种文件类型和大小限制,轻松适配不同业务场景。
-
用户体验:拖拽上传、实时预览、下载和删除功能一应俱全。
-
可复用性:子组件封装完善,可在多个父组件中快速集成。
-
国际化支持:通过 vue-i18n 实现多语言提示,适合国际化项目。
子组件:文件上传核心逻辑
子组件 UploadFiles 封装了文件上传的核心功能,包括文件类型和大小校验、上传进度管理、文件列表展示以及预览和下载功能。以下是完整的子组件代码:
<template>
<div class="w-full upload-file">
<el-upload
ref="fileUpload"
v-if="props.type === 'default'"
:action="baseURL + other.adaptationUrl(props.uploadFileUrl)"
:before-upload="handleBeforeUpload"
:file-list="fileList"
:headers="headers"
:limit="limit"
:on-error="handleUploadError"
:on-remove="handleRemove"
:on-exceed="handleExceed"
:data="formData"
:auto-upload="autoUpload"
:on-success="handleUploadSuccess"
class="upload-file-uploader"
drag
multiple
:show-file-list="false"
>
<el-icon size="60" color="#999999"><UploadFilled /></el-icon>
<div class="el-upload__text">
{
{ $t('excel.operationNotice') }}
<em>{
{ $t('excel.clickUpload') }}</em>
</div>
<template #tip>
<div class="el-upload__tip" v-if="props.isShowTip">
{
{ $t('excel.pleaseUpload') }}
<template v-if="props.fileSize">
{
{ $t('excel.size') }} <b style="color: #f56c6c">{
{ props.fileSize }}MB</b>
</template>
<template v-if="props.fileType">
{
{ $t('excel.format') }} <b style="color: #f56c6c">{
{ props.fileType.join('/') }}</b>
</template>
{
{ $t('excel.file') }}
</div>
</template>
</el-upload>
<div class="file-list" v-if="fileList.length > 0">
<el-table :data="fileList" style="width: 100%">
<el-table-column prop="original" label="文件名" />
<el-table-column label="操作" width="250">
<template #default="scope">
<el-button size="small" type="primary" link @click="handlePreview(scope.row)">
<el-icon><View /></el-icon> 查看
</el-button>
<el-button size="small" type="success" link @click="handleDownload(scope.row)">
<el-icon><Download /></el-icon> 下载
</el-button>
<el-button size="small" type="danger" link @click="handleRemove(scope.row)">
<el-icon><Delete /></el-icon> 删除
</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
</template>
<script setup lang="ts" name="upload-file">
import { ref, computed, watch } from 'vue';
import { useMessage } from '/@/hooks/message';
import { Session } from '/@/