SoFunction
Updated on 2025-04-05

Combining the el-upload component to realize the function of uploading large files shards

Introduction

I believe everyone is familiar with the el-upload upload component of Element UI. Recently, I have received a new requirement, requiring the shard upload function to be implemented based on the el-upload component, that is, files less than or equal to 5M are uploaded normally, and files greater than 5M are cut into 5M for each slice to be uploaded. So how to implement this function? Let's take a look together

Code implementation

First, we need to set the http-request of the el-upload component, so that the default upload behavior can be overridden and the upload implementation can be customized.

<!-- dataIt is an additional parameter that comes with upload,uploadFileIt is the method to override the default upload -->
<el-upload :data="data" :http-request="uploadFile">
    <el-button icon="el-icon-upload2">Local files</el-button>
</el-upload>

Next, the uploadFile method needs to distinguish whether the file exceeds 5M

async uploadFile({ data, file }) {
  // data is an extra parameter that comes with upload, file is a file  let url = "xxx" //Upload file interface  let loadingInstance = ({
    text: "Uploading files, please wait...",
  });
  try {
    // If the file is less than 5MB, upload it directly    if ( < 5 * 1024 * 1024) {
      let formData = new FormData();
      for (let key in data) {
        (key, data[key]);
      }
      ("file", file);

      const res = await upload(url,formData);
      ();
      return res;
    } else {
      // If the file is greater than or equal to 5MB, upload the fragment       = file;
      const res = await uploadByPieces(url,data);
      ();
      return res;
    }
  } catch (e) {
    ();
    return e;
  }
}

The upload method is a normal upload method. uploadByPieces is a shard upload method. We can put them in a separate js file for us to use.

upload method:

const upload = (url, data, headers = {}) => {
    return new Promise((resolve, reject) => {
        axios({
            url,
            method: "post",
            data,
            headers: {
                ...headers,
                'Content-Type': 'multipart/form-data'
            }
        }).then(res => {
            return resolve()
        }).catch(err => {
            return reject(err)
        })
    })
}

In the uploadByPieces method we can use slice the file using

// Variables used during uploadingconst chunkSize = 5 * 1024 * 1024; // 5MB per piececonst chunkCount = ( / chunkSize); // Total number of films// Get the current chunk dataconst getChunkInfo = (file, index) => {
    let start = index * chunkSize;
    let end = (, start + chunkSize);
    let chunk = (start, end);
    return { start, end, chunk };
};

The File object does not define any method, but it inherits the slice method from the Blob object:MDN

Complete code

<template>
    <el-upload :data="data" :http-request="uploadFile">
        <el-button icon="el-icon-upload2">File upload</el-button>
    </el-upload>
</template>
<script>
//Introduce upload file methodimport { upload, uploadByPieces } from "@/utils/";
// Loading
import { Loading } from "element-ui";

export default {
    props: ["data"],
    methods: {
        async uploadFile({ data, file }) {
          // data is an extra parameter that comes with upload, file is a file          let url = "xxx" //Upload file interface          let loadingInstance = ({
            text: "Uploading files, please wait...",
          });
          try {
            // If the file is less than 5MB, upload it directly            if ( < 5 * 1024 * 1024) {
              let formData = new FormData();
              for (let key in data) {
                (key, data[key]);
              }
              ("file", file);

              const res = await upload(url,formData);
              ();
              return res;
            } else {
              // If the file is greater than or equal to 5MB, upload the fragment               = file;
              const res = await uploadByPieces(url,data);
              ();
              return res;
            }
          } catch (e) {
            ();
            return e;
          }
        }
    }
}
</script>

import axios from "axios";
//Upload normallyconst upload = (url, data, headers = {}) => {
    return new Promise((resolve, reject) => {
        axios({
            url,
            method: "post",
            data,
            headers: {
                ...headers,
                'Content-Type': 'multipart/form-data'
            }
        }).then(res => {
            return resolve()
        }).catch(err => {
            return reject(err)
        })
    })
}
//Shash uploadconst uploadByPieces = async (url,{ fileName, file }) => {
    // Variables used during uploading    const chunkSize = 5 * 1024 * 1024; // 5MB per piece    const chunkCount = ( / chunkSize); // Total number of films    // Get the current chunk data    const getChunkInfo = (file, index) => {
        let start = index * chunkSize;
        let end = (, start + chunkSize);
        let chunk = (start, end);
        return { start, end, chunk };
    };
    // Shard upload interface    const uploadChunk = (data) => {
        return new Promise((resolve, reject) => {
            axios({
                url,
                method: "post",
                data,
                headers: {
                    'Content-Type': 'multipart/form-data'
                }
            }).then(res => {
                return resolve()
            }).catch(err => {
                return reject(err)
            })
        })
    }
    // chunk upload for a single file    const readChunk = (index) => {
        const { chunk } = getChunkInfo(file, index);
        let fetchForm = new FormData();
        ("chunk", chunk);
        ("index", index);
        ("chunkCount", chunkCount);
        return uploadChunk(fetchForm)
    };
    // chunk processing for each file    const promiseList = []
    try {
        for (let index = 0; index < chunkCount; ++index) {
                (readChunk(index))
        }
        const res = await (promiseList)
        return res
    }catch (e) {
        return e
    }
}

export { upload, uploadByPieces }

This is the article about combining the el-upload component to achieve large file fragment uploads. For more related contents of el-upload large file fragment uploads, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!