原因:我并没有用el-upload上面的action设置上传url,也没有用他自带的方法上传
这里我使用的是通过自定义接口手动上传,即点击外部按钮,将文件转换后调用接口将文件传参,拿到存储后转换回来的文件url,直接调用接口上传,没有用到action,以及upload上的submit方法等
自定义接口上传文件
<el-upload :auto-upload="false" accept=".mp4,.avi,.mp3,.png,.jpg,.jpeg,.gif,.bmp,.webp,.svg" dragv-model:file-list="fileList" :on-preview="handlePictureCardPreview" ref="upload" :on-progress="handleProgress"><div class="el-upload__text">拖拽文件到这里 或者 <em>点击选择文件</em></div>
</el-upload>
<el-button @click='sureUpload'>上传</el-button>
methods:{sureUpload(){for (const file of this.fileList) {if (file.status !== 'ready') {continue}let res = await this.uploadEleFile(file)if (res) {file.url = res.linkfile.name=res.originalName}}},uploadEleFile(file){const formData = new FormData();formData.append('file', file.raw);return new Promise(async (resolve,reject)=>{let res;try {res = await axios.post(baseUrl + '/form/material/upload', formData, {headers: {'Authorization': userStore.token,// 不要手动设置 Content-Type,Axios 会自动处理//'Content-Type': 'multipart/form-data'},// 监听上传进度onUploadProgress: (progressEvent) => {if (progressEvent.progress) {const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);// 更新进度file.percentage = percentCompleted;// console.log(`Upload progress: ${percentCompleted}%`);}},});if(res.status===200){file.status = 'success'resolve(res.data.data)}} catch (error) {file.status = 'fail'this.$message.error('上传失败,请重新选择素材进行上传')reject(error)}})}
}
可以上传文件,但会发现,el-upload自带的进度条不显示了
这里我尝试了很多方法都不行,例如:监听上传进度更新进度时触发up-load的钩子函数等,都不能显示进度条
因此,我只能在插槽中自定义文件列表来显示进度条
<el-upload :auto-upload="false" accept=".mp4,.avi,.mp3,.png,.jpg,.jpeg,.gif,.bmp,.webp,.svg" drag
v-model:file-list="fileList" :on-preview="handlePictureCardPreview" ref="upload" :on-progress="handleProgress"><template #default><div class="el-upload__text">拖拽文件到这里 或者 <em>点击选择文件</em></div></template>//自定义文件列表<template #file="{file}"><div class="file-list-item cursor-pointer"><span>{{ file.name }}</span><el-progress class="mt-2" :stroke-width="3" color="#409eff" v-if="file.status === 'uploading'" :percentage="file.percentage" /></div></template>
</el-upload>
<el-button @click='sureUpload'>上传</el-button>
这时候进度条了,但有一个问题是,我的file文件对象中的status没有uploading,未上传的文件和正在上传的文件status都是’ready’,如果没有这种情况的朋友可忽略这里
<el-progress class="mt-2" :stroke-width="3" color="#409eff" v-if="file.status === 'ready'" :percentage="file.percentage" />
//设置为ready就可以显示出来进度条了,但还没有上传时也会显示出来,这里没办法又加上了限制条件
<el-progress class="mt-2" :stroke-width="3" color="#409eff" v-if="file.status === 'ready' && file.percentage !== 0" :percentage="file.percentage" />
//加上限制条件后未上传时不显示进度条了,但也会有问题,如果上传文件较小,监听进度时,进度条直接就为100了,由于进度条100后就不显示,因此页面上看不到有显示进度条的变化,即一直不显示进度条
显示进度条后又有了新的问题
通过插槽实现自定义进度条显示后,覆盖了默认的el-upload文件渲染,因此,文件后的状态以及删除文件的功能没有了,因此自定义文件列表时,除了进度条,还要自定义一下上传状态(例如:成功/失败)和删除文件
最终结果
//结构
<template #file="{file}"><div class="file-list-item cursor-pointer"><!-- 点击预览 --><span @click="handlePictureCardPreview(file)" class="flex-1">{{ file.name }}</span><!-- 显示进度条 --><el-progress class="mt-2" :stroke-width="3" color="#409eff" v-if="file.status === 'ready' && file.percentage !== 0" :percentage="file.percentage" /><!-- 显示文件上传状态 --><span v-if="file.status === 'success'" style="color: green;"><el-icon><CircleCheck /></el-icon></span><span v-if="file.status === 'fail'" style="color: red;"><el-icon><CircleClose /></el-icon></span><!-- 删除文件 --><el-button class="w-[50px] h-[32px] border-[0] text-[20px] delete-btn" icon="close" @click="handleRemove(file)" /></div></template>
//js
methods:{
handleRemove(file){// 删除文件的方法const index = this.fileList.indexOf(file);if (index !== -1) {this.fileList.splice(index, 1); // 从 fileList 中删除文件}},
},
handlePictureCardPreview(file) {let urlif (file.status === 'success') {url = file.url} else {url = URL.createObjectURL(file.raw)}//判断url是否图片 png jpg jpeg giflet reg = /\.(png|jpg|jpeg|gif|svg|ico)$/if (reg.test(url) || file.raw?.type.includes('image')) {this.dialogImageUrl = urlthis.dialogVisible = truereturn}window.open(url, '_blank');},
//css样式
<style scoped lang="scss">
.file-list-item {display: flex;justify-content: space-between;align-items: center;margin-bottom: 10px;
}
/* 隐藏删除按钮,只有鼠标悬浮时显示 */
.delete-btn {display: none;position: absolute;right: 0;
}/* 鼠标悬浮时,显示删除按钮 */
.file-list-item:hover .delete-btn {display: inline-block;
}
</style>