“This is my seventh day of the November Gwen Challenge.The final text challenge in 2021”

I recently had a task to write an upload page, which is a background page, so I preferred to use

in Element-UI.

Since fragment upload is required, we define the upload event HTTP-Request, but when we check with the background, we find that the progress bar in the file-list is not…. , it just happens that the effect picture provided by UI is a little different from that provided by Upload, so please customize it.

1. Part of the page code

  • Hide the default file-list list
  • Declare a custom upload eventhttp-request
<el-upload
    class="upload-demo"
    ref="upload"
    action="/"
    multiple // Multiple file uploads
    :action="uploadUrl" // File upload address (required)
    :show-file-list="false" // Custom styles so set false not to display
    :file-list="fileArr"// List of files
    :http-request="checkedFile" // Customize the upload event
    :before-upload="beforeUploadFile" // Before uploading the file
    :on-progress="uploadFileProcess" // File transfer process (processing progress bar)
    :on-success="handleFileSuccess" // File succeeded >
        <el-button size="small" type="primary"</el-button> </el-upload>Copy the code

2. Part of js code

// Format the file size to display text
 getSize(size) {
    return size > 1024
      ? size / 1024 > 1024
        ? size / (1024 * 1024) > 1024
          ? (size / (1024 * 1024 * 1024)).toFixed(2) + 'GB'
          : (size / (1024 * 1024)).toFixed(2) + 'MB'
        : (size / 1024).toFixed(2) + 'KB'
      : size.toFixed(2) + 'B'
  },
async checkedFile(options) {
    const { maxSize, multiUploadSize, getSize, splitUpload, singleUpload } =
      this
    const { file, onProgress, onSuccess, onError } = options
    console.log('options', options, this)
    if (file.size > maxSize) {
      return this.$message({
        message: 'The file you selected is greater than${getSize(maxSize)}`.type: 'error'})},// Upload slices larger than the specified size
    const uploadFunc = file.size > multiUploadSize
        ? splitUpload
        : singleUpload
    try {
      let info = await uploadFunc(file, onProgress)
      this.$message({
        message: info.msg || 'Upload successful'.type: 'success',
      })
      onSuccess()
    } catch (e) {
      console.error('error', e)
      onError()
    }
    const prom = new Promise((resolve, reject) = > {})
    prom.abort = () = > {}
    return prom
  },
// Upload large files in chunks
  splitUpload(file, onProgress) {
    return new Promise(async (resolve, reject) => {
      try {
        const { eachSize } = this
        const chunks = Math.ceil(file.size / eachSize)
        const fileChunks = await this.splitFile(file, eachSize, chunks)
        let currentChunk = 1
        let cbRes = []
        for (let i = 1; i <= fileChunks.length; i++) {
          CurrentChunk = currentChunk = currentChunk = currentChunk = currentChunk = currentChunk
          console.log('before', currentChunk, i)
          if (currentChunk === i) {
            // After each block is uploaded, the index of the next block to be submitted is returned
            let postRes = await this.postFile(
              {
                // chunked: true,
                chunk: i,
                chunks,
                // eachSize,
                name: file.name,
                totalSize: file.size,
                // uid: file.uid,
                model: this.model,
                file: fileChunks[i - 1],
              },
              onProgress
            )
            // Determine whether to continue according to the actual interface format
            let status = postRes.key
            if (status === 'continue') {
              currentChunk = postRes.value
            } else if (status === 'hasValue') {
              currentChunk = postRes.value + 1
            } else if (status === 'success') {
              currentChunk = postRes.value
              cbRes = postRes
            } else {
              currentChunk = postRes.value
            }
            console.log('after currentChunk', currentChunk)
          }
        }
        resolve(cbRes)
      } catch (e) {
        reject(e)
      }
    })
  },
  // Split the file into blocks using array.prototype. slice
  splitFile(file, eachSize, chunks) {
    return new Promise((resolve, reject) = > {
      try {
        setTimeout(() = > {
          const fileChunk = []
          for (let chunk = 0; chunks > 0; chunks--) {
            fileChunk.push(file.slice(chunk, chunk + eachSize))
            chunk += eachSize
          }
          resolve(fileChunk)
        }, 0)}catch (e) {
        console.error(e)
        reject(new Error('File chunking error'))}})},// Submit the file method, convert the parameters to FormData, and then make the request through AXIOS
  postFile(param, onProgress) {
    const formData = new FormData()
    for (let p in param) {
      formData.append(p, param[p])
    }
    const { requestCancelQueue } = this
    const config = {
      cancelToken: new axios.CancelToken(function executor(cancel) {
        if (requestCancelQueue[param.uid]) {
          requestCancelQueue[param.uid]()
          delete requestCancelQueue[param.uid]
        }
        requestCancelQueue[param.uid] = cancel
      }),
      onUploadProgress: (e) = > {
        console.log('onUploadProgress', e, param, this)
        if (param.chunked) {
          e.percent = Number(
            (
              ((param.chunk * (param.eachSize - 1) + e.loaded) /
                param.fullSize) *
              100
            ).toFixed(2))}else {
          e.percent = Number(((e.loaded / e.total) * 100).toFixed(2))
        }
        onProgress(e)
      },
    }
    // Actual upload event
    if (this.fileType === 0) {
      return uploadStructTree(formData, config).then((rs) = > rs)
    } else if (this.fileType === 2) {
      return uploadTheory(formData, config).then((rs) = > rs)
    } else if (this.fileType === 3) {
      return uploadDmo(formData, config).then((rs) = > rs)
    } else {
      return upload3DToBos(formData, config).then((rs) = > rs)
    }
  },
Copy the code