refactor: ♻️ 重构了文件上传,解决文件上传不显示进度条的问题

重构了文件上传,解决文件上传不显示进度条的问题,现在多选文件上传时,每个文件有单独的进度条
This commit is contained in:
theo
2025-08-28 11:59:15 +08:00
parent e37a6c5aa4
commit ab829060f1
2 changed files with 35 additions and 41 deletions

View File

@@ -1,13 +1,19 @@
import request from "@/utils/request";
const FileAPI = {
/** 上传文件 */
upload(formData: FormData) {
/** 上传文件 (传入 FormData上传进度回调 */
upload(formData: FormData, onProgress?: (percent: number) => void) {
return request<any, FileInfo>({
url: "/api/v1/files",
method: "post",
data: formData,
headers: { "Content-Type": "multipart/form-data" },
onUploadProgress: (progressEvent) => {
if (progressEvent.total) {
const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total);
onProgress?.(percent);
}
},
});
},

View File

@@ -6,7 +6,6 @@
:style="props.style"
:before-upload="handleBeforeUpload"
:http-request="handleUpload"
:on-progress="handleProgress"
:on-success="handleSuccess"
:on-error="handleError"
:accept="props.accept"
@@ -20,25 +19,24 @@
<!-- 文件列表 -->
<template #file="{ file }">
<div class="el-upload-list__item-info">
<a class="el-upload-list__item-name" @click="handleDownload(file)">
<el-icon><Document /></el-icon>
<span class="el-upload-list__item-file-name">{{ file.name }}</span>
<span class="el-icon--close" @click.stop="handleRemove(file.url!)">
<el-icon><Close /></el-icon>
</span>
</a>
</div>
<template v-if="file.status === 'success'">
<div class="el-upload-list__item-info">
<a class="el-upload-list__item-name" @click="handleDownload(file)">
<el-icon><Document /></el-icon>
<span class="el-upload-list__item-file-name">{{ file.name }}</span>
<span class="el-icon--close" @click.stop="handleRemove(file.url!)">
<el-icon><Close /></el-icon>
</span>
</a>
</div>
</template>
<template v-else>
<div class="el-upload-list__item-info">
<el-progress style="display: inline-flex" :percentage="file.percentage" />
</div>
</template>
</template>
</el-upload>
<el-progress
:style="{
display: showProgress ? 'inline-flex' : 'none',
width: '100%',
}"
:percentage="progressPercent"
/>
</div>
</template>
<script lang="ts" setup>
@@ -47,7 +45,6 @@ import {
UploadUserFile,
UploadFile,
UploadFiles,
UploadProgressEvent,
UploadRequestOptions,
} from "element-plus";
@@ -111,7 +108,6 @@ const props = defineProps({
},
},
});
const modelValue = defineModel("modelValue", {
type: [Array] as PropType<FileInfo[]>,
required: true,
@@ -120,9 +116,6 @@ const modelValue = defineModel("modelValue", {
const fileList = ref([] as UploadFile[]);
const showProgress = ref(false);
const progressPercent = ref(0);
// 监听 modelValue 转换用于显示的 fileList
watch(
modelValue,
@@ -160,7 +153,6 @@ function handleBeforeUpload(file: UploadRawFile) {
function handleUpload(options: UploadRequestOptions) {
return new Promise((resolve, reject) => {
const file = options.file;
const formData = new FormData();
formData.append(props.name, file);
@@ -168,26 +160,22 @@ function handleUpload(options: UploadRequestOptions) {
Object.keys(props.data).forEach((key) => {
formData.append(key, props.data[key]);
});
FileAPI.upload(formData)
.then((data) => {
resolve(data);
FileAPI.upload(formData, (percent) => {
const uid = file.uid;
const fileItem = fileList.value.find((file) => file.uid === uid);
if (fileItem) {
fileItem.percentage = percent;
}
})
.then((res) => {
resolve(res);
})
.catch((error) => {
reject(error);
.catch((err) => {
reject(err);
});
});
}
/**
* 上传进度
*
* @param event
*/
const handleProgress = (event: UploadProgressEvent) => {
progressPercent.value = event.percent;
};
/**
* 上传成功
*/