在現代Web開發中,文件上傳功能是許多應用的核心需求之一。無論是企業管理系統、內容管理系統還是醫療信息系統,上傳附件的功能都至關重要。本文將分享一個基于 Vue3 和 Element Plus 實現的文件上傳組件,結合父子組件的協作,展示如何構建一個功能強大、用戶體驗友好的文件上傳解決方案。以下是完整的代碼實現和使用指南,適合前端開發者參考和復用。
為什么選擇這個解決方案?
-
靈活性:支持多種文件類型和大小限制,輕松適配不同業務場景。
-
用戶體驗:拖拽上傳、實時預覽、下載和刪除功能一應俱全。
-
可復用性:子組件封裝完善,可在多個父組件中快速集成。
-
國際化支持:通過 vue-i18n 實現多語言提示,適合國際化項目。
子組件:文件上傳核心邏輯
子組件 UploadFiles 封裝了文件上傳的核心功能,包括文件類型和大小校驗、上傳進度管理、文件列表展示以及預覽和下載功能。以下是完整的子組件代碼:
<template><div class="w-full upload-file"><el-uploadref="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"dragmultiple: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 '/@/