完整代碼
upload.vue
<template>
<el-upload :data="data" :http-request="uploadFile">
<el-button icon="el-icon-upload2">文件上傳</el-button>
</el-upload>
</template>
<script>
// 引入上傳文件方法
import { upload, uploadByPieces } from "@/utils/upload.js";
export default {
props: ["data"],
methods: {
async uploadFile({ data, file }) {
// data是上傳時附帶的額外參數,file是文件
let url = "xxx" //上傳文件接口
let loadingInstance = Loading.service({
text: "正在上傳文件,請稍后...",
});
try {
// 如果文件小於5MB,直接上傳
if (file.size < 5 * 1024 * 1024) {
let formData = new FormData();
for (let key in data) {
formData.append(key, data[key]);
}
formData.append("file", file);
const res = await upload(url,formData);
loadingInstance.close();
return res;
} else {
// 如果文件大於等於5MB,分片上傳
data.file = file;
const res = await uploadByPieces(url,data);
loadingInstance.close();
return res;
}
} catch (e) {
loadingInstance.close();
return e;
}
}
}
}
</script>
upload.js
import axios from "axios"; //正常上傳 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(res.data) }).catch(err => { return reject(err) }) }) } //分片上傳 const uploadByPieces = async (url,{ fileName, file }) => { // 上傳過程中用到的變量 const chunkSize = 5 * 1024 * 1024; // 5MB一片 const chunkCount = Math.ceil(file.size / chunkSize); // 總片數 // 獲取當前chunk數據 const getChunkInfo = (file, index) => { let start = index * chunkSize; let end = Math.min(file.size, start + chunkSize); let chunk = file.slice(start, end); return { start, end, chunk }; }; // 分片上傳接口 const uploadChunk = (data) => { return new Promise((resolve, reject) => { axios({ url, method: "post", data, headers: { 'Content-Type': 'multipart/form-data' } }).then(res => { return resolve(res.data) }).catch(err => { return reject(err) }) }) } // 針對單個文件進行chunk上傳 const readChunk = (index) => { const { chunk } = getChunkInfo(file, index); let fetchForm = new FormData(); fetchForm.append("chunk", chunk); fetchForm.append("index", index); fetchForm.append("chunkCount", chunkCount); return uploadChunk(fetchForm) }; // 針對每個文件進行chunk處理 const promiseList = [] try { for (let index = 0; index < chunkCount; ++index) { promiseList.push(readChunk(index)) } const res = await Promise.all(promiseList) return res }catch (e) { return e } } export { upload, uploadByPieces }
