本文将详细介绍一个基于 Vue.js 的分片上传组件的设计与实现,该组件支持大文件分片上传进度显示等功能。
组件概述
这个上传组件主要包含以下功能:
- 支持大文件分片上传(默认5MB一个分片)
- 支持文件哈希计算,用于文件唯一标识
- 显示上传进度(整体和单个文件)
- 支持自定义UI样式
- 提供完整的文件管理功能(添加、删除)
- 后端支持分片合并和临时存储
组件结构
组件由三个主要文件组成:
Uploader.vue
- 主组件fileChunk.ts
- 文件分片和哈希计算工具uploader.post.ts
- 后端API处理uploaderImg.vue
- 调用示例
核心功能实现
1. 文件分片处理
在 fileChunk.ts
中,我们实现了文件分片功能:
import SparkMD5 from 'spark-md5';
/*** 创建文件分片* @param file 文件对象* @param chunkSize 每个分片的大小 (字节)*/
export const createFileChunk = (file: File, chunkSize: number) => {const chunks = []let current = 0while (current < file.size) {const end = Math.min(current + chunkSize, file.size)const chunk = file.slice(current, end)chunks.push({file: chunk,index: chunks.length,start: current,end: end,size: end - current,})current = end}return chunks
}/*** 计算文件hash (使用SparkMD5)* @param file 文件对象*/
export const calculateHash = (file: File): Promise<string> => {return new Promise((resolve) => {const spark = new SparkMD5.ArrayBuffer()const reader = new FileReader()const chunkSize = 2 * 1024 * 1024 // 2MBconst chunks = Math.ceil(file.size / chunkSize)let currentChunk = 0reader.onload = (e) => {spark.append(e.target?.result as ArrayBuffer)currentChunk++if (currentChunk < chunks) {loadNext()} else {resolve(spark.end())}}const loadNext = () => {const start = currentChunk * chunkSizeconst end = Math.min(start + chunkSize, file.size)const chunk = file.slice(start, end)reader.readAsArrayBuffer(chunk)}loadNext()})
}
这个方法将大文件分割成指定大小的多个小分片,便于上传和管理。
2. 文件哈希计算
使用 SparkMD5 库计算文件哈希,用于唯一标识文件:
export const calculateHash = (file: File): Promise<string> => {return new Promise((resolve) => {const spark = new SparkMD5.ArrayBuffer()const reader