最近接触一个项目中用到文件上传并要求可以添加编辑上传的文件信息,将文件转成二进制流的方式传参给后端,并要求带有实时 进度条
看了网上有些资料 采用队列的解决方法,我这个项目需求方需要同时上传
需要解决的难点:
1. 进度条的展示
2. 当采用多选文件之后会发现, 上传的进度条会反复横跳(上传进度一直在变化…), 上传的文件越多, 横跳的速度, 频率就越快
3. 进度条和文件名建立对应关系
4. 判断全部文件是否全部上传完成(指的是接口调用完成,包括上传失败)
话不多说,直接上效果图和解决方案的核心代码
解决方案:
1.template
<div v-if="showProgress">
<template v-for="item in uploadFileList" :key="item.name">
<el-row :gutter="10" v-if="item.status !== 'success'">
<el-col :span="20">{{item.name}}</el-col>
<el-col :span="4">
<el-progress :text-inside="true" :stroke-width="20" :percentage="item.progress" />
</el-col>
</el-row>
</template>
</div>
<el-upload
v-loading="loading"
ref="uploadRef"
class="upload-demo"
v-model="fileList"
size="large"
:show-file-list="false"
:before-upload="beforeUpload"
:on-change="handleChange"
:on-preview="handlePreview"
:on-remove="handleRemove"
:http-request="upload"
:multiple="!item.limit || item.limit > 1"
:limit="item.limit"
>
<el-button type="primary" plain :disabled="showProgress">上传文件</el-button>
</el-upload>
<div class="file-tip">
<template v-if="item.desc">{{ item.desc }} <br/></template>
支持文件格式:{{ (item.fileType && item.fileType.join(',')) || "doc ,docx,pdf"}} ,单个文件不能超过{{item.size || 10}}MB。
</div>
Javascript 代码
let uploadFileList = ref([])
const showProgress = ref(false)
/** 上传 */
const upload = (param) => {
const { file, onProgress, onSuccess, onError } = param;
const fileData = new FormData()
fileData.append('files', file)
showProgress.value = true;
uploadFile(
fileData,
progressEvent => {
// 计算并更新上传进度
const progress = Math.round((progressEvent.loaded * 100) / progressEvent.total);
updateFileStatus(file.name, 'uploading', progress);
// onProgress(progressEvent);
}
).then(response => {
//更新显示的上传进度
updateFileStatus(file.name, 'success', 100);
ElMessage.success(`${file.name} 上传成功`);
// onSuccess(response.data);
}).catch((error)=>{
//更新显示的上传进度
updateFileStatus(file.name, 'success', 100);
ElMessage.error(`${file.name} 上传失败`);
// onError(error)
}).finally(()=>{
if (checkAllUploadsComplete()) {
showProgress.value = false;
uploadFileList.value = []
// ElMessage.success('所有文件上传成功');
}
})
}
const updateFileStatus = (name, status, progress = 0) => {
const file = uploadFileList.value.find(f => f.name === name);
if (file) {
file.status = status;
file.progress = progress;
}
};
// 检查是否全部上传完成
const checkAllUploadsComplete = () => {
return uploadFileList.value.every(file => file.status === 'success');
};
API写法:
export function uploadFile(data, onUploadProgress) {
return request({
url: "/assets/file/upload",
headers: {
repeatSubmit: false,
},
onUploadProgress,
timeout: 20000000,
method: "post",
data: data,
});
}
欢迎大家一起讨论学习😊~