vue项目手动上传文件并展示进度条
问题:
- 1.上传文件可能会跨域,查找跨域解决办法。(查找资料表明用手动上传,new FormData()方式可以解决,先用这个试一试)
- 2.手动上传没有进度条,查找进度条实现方式。(自定义axios,添加请求参数onUploadProgress)
- 3.进度条的进度和上传的对勾显示时机不一致。(解决办法让进度条卡到98%,等后台返回结果再显示到100%)
代码
<template>
<div>
<el-upload
:class="hideUpload ? 'hide' : ''"
ref="upload"
action="#"
:limit="1"
:on-remove="handleRemove"
:before-remove="beforeRemove"
:file-list="fileList"
:on-change="changUpload"
:http-request="uploadFile"
:on-exceed="handleExceed"
:auto-upload="false"
>
<el-button size="small" type="primary">选择文件 </el-button>
</el-upload>
<el-progress
v-if="showJinDuTao"
style="width: 200px; margin-top: 8px"
:percentage="progressPercent"
/>
</div>
</template>
<script>
import { checkFile, upload } from '../config/url'
export default {
data() {
return {
fileList: [],
progressPercent: 0, // 进度条默认为0
hideUpload: true, //控制上传文件时删除按钮显示隐藏
showJinDuTao: false, //控制进度条显示隐藏
fileName: '', //文件名称
}
},
methods: {
// 文件限制
handleExceed(fileList) {
this.$message.warning(
`当前限制只能上传 1 个文件,已上传 ${fileList.length} 个文件`
)
},
// 上传文件
uploadFile(item) {
let FormDatas = new FormData()
FormDatas.append('file', item.file)
this.fileName = item.file.name
this.showJinDuTao = true
this.$http({
url: upload,
method: 'post',
headers: { 'Content-Type': 'multipart/form-data' },
data: FormDatas,
timeout: 30000,
onUploadProgress: (progressEvent) => {
this.progressPercent = Number(
((progressEvent.loaded / progressEvent.total) * 100).toFixed(0)
)
// 上传进度和对勾显示时间不相符,让进度条卡到98,等后台返回结果在显示100
if (this.progressPercent >= 98) {
this.progressPercent = 98
}
},
})
.then((res) => {
if (res.data.code == 200) {
// 解决上传时删除文件了但是上传请求依然执行问题
// 解决办法:上传时删除按钮不显示,上传成功后在显示
this.hideUpload = false
this.progressPercent = 100
this.fileList = []
this.fileList.push(item.file)
// 上传成功后,进度条消失
setTimeout(() => {
this.showJinDuTao = false
this.progressPercent = 0
}, 1000)
} else {
this.showJinDuTao = false
this.progressPercent = 0
this.$refs.upload.clearFiles()
this.$message.error(res.data.message)
}
})
.catch(() => {
this.$message.error('上传文件超时')
this.showJinDuTao = false
this.progressPercent = 0
this.$refs.upload.clearFiles()
})
},
// 删除文件
handleRemove(file) {
if (!file.name) {
return
}
this.$fetch(deleteUploadFile, {
fileName: file.name,
})
.then((res) => {
if (res.code == 200) {
this.$refs.upload.clearFiles() //上传成功清除文件列表
this.$message.success(`${file.name}文件已移除`)
} else {
this.fileList = []
this.fileList.push(file)
this.$message.error(res.message)
}
})
.catch((error) => {
this.$message.error(error)
})
},
// 删除前提示
beforeRemove(file) {
return this.$confirm(`确定移除 ${file.name}?`)
},
// 上传前发请求检测文件是否已上传
changUpload(file) {
this.hideUpload = true
if (file.name) {
this.$fetch(checkFile, {
fileName: file.name,
})
.then((res) => {
if (res.code == 200) {
if (res.message == '1') {
this.$confirm('该文件已上传,要覆盖吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
.then(() => {
this.$refs.upload.submit() //调用api手动上传
})
.catch(() => {
this.$refs.upload.clearFiles() //取消时清空文件列表
})
} else if (res.message == '0') {
debugger
this.$refs.upload.submit()
}
}
})
.catch((error) => {
this.$message.error(error)
})
}
},
},
}
</script>
<style lang="less" scoped>
/deep/ .el-upload-list__item.is-success.focusing .el-icon-close-tip {
display: none !important;
}
.hide {
/deep/ .el-upload-list__item .el-icon-close {
display: none !important;
}
}
/deep/ .el-progress-bar__outer {
background-color: rgba(36, 35, 35, 0.6);
}
</style>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南