ant自定义上传文件customRequest

customRequest里面一个data参数data包含了对file文件上传状态操作例如onSuccessonProgressonError等 和file文件。
改变文件上传状态可以通过改变fileList里面filestatusrespones

踩坑:
1、在customRequest文件上传完成以后,会自动重新更新一下fileList文件。上传之前挂载file文件上的参数丢失
解决:必要参数创建一个新的list存放参数。通过文件uid关联

2、 删除文件, @remove默认会删除文件
解决需要自定义删除fileList的时候需要方法后面 return false

dom代码

  <a-upload-dragger
            v-model:file-list="fileList"
            :multiple="true"
            :max-count="10"
            :disabled="fileList?.length >= 10"
            :customRequest="customRequest"
            @remove="handleRemove"
            :progress="progress"
            accept=".onnx,.pth"
            width="248px"
          >
          </a-upload-dragger>
 const customRequest = async (data: { file: any; onProgress?: any; onSuccess?: any }) => {
    const { file, onProgress, onSuccess } = data
 }

ant自定义上传文件 显示进度条

axios请求配置onUploadProgress,通过loadedtotal计算进度自定义上传的onProgress同步进度ant组件

  const progress: UploadProps['progress'] = {
    strokeColor: {
      '0%': '#108ee9',
      '100%': '#87d068'
    },
    strokeWidth: 3,
    format: percent => `${parseFloat(percent!.toFixed(2))}%`,
    class: 'test'
  } // 上传进度条
   const customRequest = async (data: { file: any; onProgress?: any; onSuccess?: any }) => {
    const { file, onProgress, onSuccess } = data
         let config = {
          timeout: 120000, //设置超时时长
          onUploadProgress: (Progress: { loaded: number; total: number }) => {
            let percents = Math.round((Progress.loaded * 100) / Progress.total)
            // 更新进度条
            onProgress({ percent: percents }, file)
          }
        }
        let formData = new FormData()
        formData.append('file', file)
        http
          .upload(url, formData, config)
          .then(resTwo => {
          })
          .catch(() => {
          })
 }

取消上传文件 axios中断请求

axios定义一个CancelToken,生成一个token promise带到请求,当需要中断请求时候调用这个promise

  const CancelToken = axios.CancelToken
  const source = CancelToken.source()
  let config = {
          timeout: 120000, //设置超时时长
          onUploadProgress: (Progress: { loaded: number; total: number }) => {
            let percents = Math.round((Progress.loaded * 100) / Progress.total)
            // 更新进度条
            onProgress({ percent: percents }, file)
          },
          cancelToken: source.token
        }
        let formData = new FormData()
        formData.append('file', file)
        http
          .upload(url, formData, config)
          .then(resTwo => {
            onSuccess(resTwo, file)
          })
          .catch(() => {
            currenFile.status = 'error'
            currenFile.response = '上传失败'
          })
// 中断请求
source.cancel('中断上传描述 可自定义。')

axios上传文件请求封装

 import Axios, from 'axios'
 export const http ={
  upload: (url: string, formData?: object, config?: object) => {
    return Axios({
      url: url, // 接口地址
      method: 'put',
      data: formData,
      ...config
    })
  }
 }

完整定义上传代码

因为我是多文件上传,会涉及多个文件同时上传、取消中断。所以我定义一个fileTokenArr存放文件上传的token

  import { http } from '@/services/http'
  
  interface File extends UploadFile {
    id?: string // 预上传后的id
  }
  const fileList = ref<File[]>([]) // 上传文件
  // 上传进度条
  const progress: UploadProps['progress'] = {
    strokeColor: {
      '0%': '#108ee9',
      '100%': '#87d068'
    },
    strokeWidth: 3,
    format: percent => `${parseFloat(percent!.toFixed(2))}%`,
    class: 'test'
  } 
  let fileTokenArr: FileToken[] = [] // 根据上传文件创建token数组
  
  const customRequest = async (data: { file: any; onProgress?: any; onSuccess?: any }) => {
    const { file, onProgress, onSuccess } = data

    // 在fileList获取当前文件
    const fileNameList = fileList.value.map(it => it.name)
    const fileIndex = fileNameList.lastIndexOf(file.name)
    let currenFile = fileList.value[fileIndex]

    // 判断同名文件
    const newFileList = fileList.value.slice()
    newFileList.splice(fileIndex, 1)
    let index = newFileList.findIndex(item => item.name === file.name)
    if (index !== -1) {
      message.error('暂不支持上传同名文件')
      currenFile.status = 'error'
      currenFile.response = '暂不支持上传同名文件'
      return false
    }

    // 判断文件类型
    let type = data.file.name.substr(data.file.name.lastIndexOf('.') + 1)
    if (type !== 'onnx' &amp;&amp; type !== 'pth') {
      message.error('请上传onnx、pth格式的文件')
      currenFile.status = 'error'
      currenFile.response = '请上传onnx、pth格式的文件'
      return false
    }

    // 请求获取文件预上传地址和文件id
    let res = await req..............

    if (res) {
      if (res.code === 'SYSTEM-100000') {
        // axios token 用于中断请求
        const CancelToken = axios.CancelToken
        const source = CancelToken.source()
        // 存入token数组uid为文件唯一标识。存入id是为了在正在上传的时候取消预上传使用
        fileTokenArr.push({
          uid: file.uid,
          id: res.data[0].id,
          success: false,
          token: source
        })
        let uidFileIndex = fileTokenArr.findIndex(item => item.uid === currenFile.uid)

        // 根据上传地址上传问及那
        let config = {
          timeout: 120000, //设置超时时长
          onUploadProgress: (Progress: { loaded: number; total: number }) => {
            let percents = Math.round((Progress.loaded * 100) / Progress.total)
            // 更新进度
            onProgress({ percent: percents }, file)
          },
          cancelToken: source.token
        }
        let formData = new FormData()
        formData.append('file', file)
        http
          .upload(res.data[0].presignedUrl, formData, config)
          .then(resTwo => {
            onSuccess(resTwo, file)
            // 上传成功以后: fileList被重新赋值,不能用currenFile
            const fileNameList = fileList.value.map(it => it.name)
            const fileIndex = fileNameList.lastIndexOf(file.name)
            fileList.value[fileIndex].id = res.data[0].id
            // 修改token数组里的上传状态
            fileTokenArr[uidFileIndex].success = true
            console.log('success', currenFile, fileList.value, fileTokenArr)
          })
          .catch(() => {
            currenFile.status = 'error'
            currenFile.response = '上传失败'
          })
      } else {
        message.error(res.message)
        currenFile.status = 'error'
        currenFile.response = res.message
        return false
      }
    }
  }
  // 删除单个预上传文件
  const handleRemove: UploadProps['onRemove'] = async (file: File) => {

    /**
     * 查询删除文件是否在正在上传文件数组
     * Y:(上传成功:调用取消预上传接口),(正在上传:调用axios中断上传请求,并调用取消预上传接口)
     * N: 从fileList移除该文件
     */
    let uidFileTokenIndex = fileTokenArr.findIndex(item => item.uid === file.uid)
    // 通过前端校验-已调用预上传接口
    if (uidFileTokenIndex !== -1) {
      // 未上传完成,正在上传
      if (!fileTokenArr[uidFileTokenIndex].success &amp;&amp; file.status === 'uploading') {
        // 中断上传请求
        fileTokenArr[uidFileTokenIndex].token.cancel('中断上传。')
        // 移除文件操作
        ············
      } else {
        // 已上传完成-调用取消预上传接口
         // 移除文件操作
        ············
      }
    } else {
      // 前端判断失败的文件  (没有走预上传)
      const index = fileList.value.indexOf(file)
      const newFileList = fileList.value.slice()
      newFileList.splice(index, 1)
      fileList.value = newFileList
      return
    }
    return false
  }

原文地址:https://blog.csdn.net/flowerSmiler/article/details/128555281

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_35656.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注