乐趣区

关于javascript:antdvue-upload自定义下载文件

性能要求:上传文件后点击已上传的文件,实现图片格式与 pdf 格局的文件关上预览文档格局的文件点击下载并且下载时候的文件名与上传时保持一致。

问题
因为后盾为了解决可能呈现的雷同文件名上传而导致后传的文件笼罩上一次文件的状况,就在文件上传至服务器后在文件名前面加一串随机串。这样导致在接口返回给前端的 url 的地址上会变成 文件名 + 随机字符串。同时,这样就导致前端也呈现一个状况:如果间接用 a -upload 组件封装的点击事件进行文件下载,下载后的文件名后会有一串随机字符串。这样就不合乎需要要求的保障下载时的文件名称与上传统一,为此,就须要自定义一下 a -upload 的点击下载事件。

景象

呈现起因:
a-upload 组件在上传了文件后,主动生成了 a 标签,点击文件时触发 a 标签的下载事件。如图

解决

<div class="divBox" v-for="(item, index) uploadList" :key="item.title">
  <span v-if="item.title" class="divBox-title">{{item.title}}:</span>
  <a-upload
    v-model:file-list="item.fileList"
    :customRequest="customRequest"
    :beforeUpload="beforeUpload"
    :accept="item.accept"
    @preview="previewFile"
  >
    <a-button :loading="item.loading" :disabled="item.loading"> Upload </a-button>
  </a-upload>
</div>
const uploadList = ref([]) // 文件数组
const fIndex = ref() // 以后上传数据索引

// 上传
const customRequest = file => {const api = uploadList[fIndex.value].api
  const maxNum = uploadList[fIndex.value].maxNum
  const formData = new FormData()
  formData.append('file', file.file)
  //  去除后缀指定文件名
  formData.append('fileName', file.file.name.substring(0, file.file.name.lastIndexOf('.'))) 
  // 获取以后文件上传前文件数量
  const listNum = uploadList[fIndex.value].fileList.length
  request
    .post(url, formData)
    .then(res => {if (res.result == 0) {
        // 上传胜利贮存 url
        uploadList[fIndex.value].fileList[uploadList[fIndex.value].fileList.length - 1].url = res.data.url
          const params = {url: res.data.url}
          request.post(api, params).then(result => {if (result.result == 0) {file.onSuccess(res, file.file)
            // 上传胜利判断是否超出文件数量
            if (listNum >= maxNum) {
              // 超出文件数量删除第一项文件
              uploadList[fIndex.value].fileList.shift()}
          } else {message.error(result.message)
            uploadList[fIndex.value].fileList.splice(listNum, 1)
          }
          uploadList[fIndex.value].loading = false
        })
        .catch(() => {uploadList[fIndex.value].loading = false
        })
        .finally(() => {
          // 申请完结更改为完结状态
          uploadList[fIndex.value].loading = false
        })
      } else {uploadList[fIndex.value].fileList.splice(listNum, 1)
      }
    })
    .catch(() => {
      // 上传失败
      uploadList[fIndex.value].fileList.splice(listNum, 1)
    })
}

// 上传前事件
const beforeUpload = (file, fileList) => {const size = uploadList[fIndex.value].size
  const maxNum = uploadList[fIndex.value].maxNum
  const fileLists = uploadList[fIndex.value].fileList
  const isVerify = uploadList[fIndex.value].isVerify
  const accept = uploadList[fIndex.value].accept
  const isLt = file.size / 1024 / 1024 < size
  // 校验文件格局
  let type = false
  accept.split(',').forEach(e => {const filetype = file.name.split('.')[file.name.split('.').length - 1]
    if ('.' + filetype == e) {type = true}
  })
  if (!type) {message.error('文件格式谬误,请从新上传')
    fileList.pop()
    return false
  } else {
    // 校验文件数量
    if (fileLists.length < maxNum) {
      // 校验文件大小
      if (!isLt) {message.error('文件大小超出' + size + 'M,请批改后从新抉择文件')
        fileList.pop()
        return false
      } else {return true}
    } else {if (isVerify) {return true} else {message.error('上传数量不能超过' + maxNum + '个')
        fileList.pop()
        return false
      }
    }
  }
}

// 自定义的下载和预览办法
const previewFile = item => {
  // 依据文件的后缀进行预览或是下载操作
  if (item.name.endsWith('.jpg') || item.name.endsWith('.png')) {const imgWindow = window.open('')
    imgWindow && imgWindow.document.write(`<image src='${item.url}' style='display: flex; margin: 0 auto'/>`)
  } else if (item.name.endsWith('.pdf')) {window.open(item.url + '?response-content-type=application/pdf')
  } else {if (item.url) {downloadFile(item.url, item.name)
    }
  }
}

// 下载文件 将后盾返回的文件 url 链接转换为文件流格局,点击关上新窗口下载文件
const downloadFile = async (url, fileName = null) => {const a = document.createElement('a') // 创立 a 标签
  if (fileName) {const response = await fetch(url) // 内容转变成 blob 地址
    const blob = await response.blob() // 创立暗藏的可下载链接
    const objectUrl = window.URL.createObjectURL(blob)
    a.href = objectUrl
    a.download = fileName
  } else {a.href = url}
  a.click()
  a.remove()}

这样就能够将文件依照需要要求进行下载和预览

退出移动版