vue实现分段上传
实现分段上传的基本思路
分段上传(分片上传)是将大文件分割为多个小块分别上传,最后在服务端合并的技术。Vue 中可通过前端分片、并发上传、进度监控等方式实现。

前端文件分片处理
使用 JavaScript 的 Blob.slice() 方法对文件进行分片。假设每片大小为 2MB:

function createFileChunks(file, chunkSize = 2 * 1024 * 1024) {
const chunks = [];
let start = 0;
while (start < file.size) {
const end = Math.min(start + chunkSize, file.size);
chunks.push(file.slice(start, end));
start = end;
}
return chunks;
}
上传逻辑实现
通过 FormData 封装分片数据,使用 axios 或其他 HTTP 库上传:
async function uploadChunk(chunk, index, fileHash) {
const formData = new FormData();
formData.append('chunk', chunk);
formData.append('index', index);
formData.append('hash', fileHash);
return axios.post('/api/upload', formData, {
onUploadProgress: (e) => {
// 更新单个分片的上传进度
}
});
}
并发控制与进度计算
通过 Promise.all 或并发队列控制同时上传的分片数量,并计算整体进度:
async function uploadAllChunks(chunks, fileHash, maxConcurrency = 3) {
const progressList = Array(chunks.length).fill(0);
const pool = new Set();
for (let i = 0; i < chunks.length; i++) {
const task = uploadChunk(chunks[i], i, fileHash).then(() => {
pool.delete(task);
});
pool.add(task);
if (pool.size >= maxConcurrency) {
await Promise.race(pool);
}
}
await Promise.all(pool);
}
服务端配合要点
- 分片接收:服务端需提供接口接收分片,保存为临时文件,记录分片索引。
- 合并请求:当所有分片上传完成后,前端发送合并请求,服务端按顺序拼接分片。
- 断点续传:前端上传前先查询已上传的分片列表,跳过已上传部分。
完整示例代码
<template>
<input type="file" @change="handleFileChange" />
<button @click="startUpload">上传</button>
<div>总进度: {{ totalProgress }}%</div>
</template>
<script>
export default {
data() {
return {
file: null,
totalProgress: 0
};
},
methods: {
handleFileChange(e) {
this.file = e.target.files[0];
},
async startUpload() {
const chunks = createFileChunks(this.file);
const fileHash = await this.calculateHash();
await uploadAllChunks(chunks, fileHash);
// 发送合并请求
await axios.post('/api/merge', { hash: fileHash });
},
calculateHash() {
// 使用 SparkMD5 等库计算文件唯一哈希
}
}
};
</script>
优化建议
- 文件哈希生成:使用 Web Worker 计算文件 MD5,避免主线程阻塞。
- 暂停/恢复功能:记录已上传分片信息,重新上传时跳过已完成部分。
- 错误重试机制:对失败的分片自动重试上传。
- 分片大小动态调整:根据网络状况动态改变分片大小。
以上方案需配合后端接口实现完整的断点续传功能。服务端需要设计分片存储、校验和合并逻辑。






