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>

posted @   崛起崛起  阅读(1583)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示