Vue + Element Plus 实战:大文件切片上传 + 断点续传

好的!下面是一篇结合 Element Plus 的 Vue 3 大文件切片上传 + 断点续传完整实战教程,UI 用的是 Element Plus,结构清晰,语气亲和,适合你直接复制使用。


整理不易,如果本文对你有帮助,欢迎点个【赞 👍】+【收藏 ⭐】+【关注 🧡】

📦 Vue + Element Plus 实战:大文件切片上传 + 断点续传

今天我们来用 Vue 3 + Element Plus,实战开发一个"支持大文件切片上传、断点续传"的文件上传组件,适合上传视频、压缩包、设计图等大文件场景,带完整前端逻辑和 UI 演示👇


🧩一、功能亮点

✅ 文件切片(Blob 分片)

✅ 并发上传,支持进度条

✅ 秒传校验(文件 hash)

✅ 断点续传(跳过已上传)

✅ 合并通知(服务端拼接)


✨二、最终效果图


(上传进度 + 支持断点续传)


🛠️三、完整前端实现(Element Plus 版本)

1️⃣ 安装依赖

bash 复制代码
npm install element-plus spark-md5

2️⃣ 组件模板(UploadChunk.vue)

html 复制代码
<template>
  <el-card>
    <el-upload
      :show-file-list="false"
      :before-upload="handleBeforeUpload"
      :http-request="handleUpload"
      drag
      accept="*"
    >
      <i class="el-icon-upload" />
      <div class="el-upload__text">将文件拖到此处,或 <em>点击上传</em></div>
    </el-upload>

    <el-progress
      v-if="uploadProgress > 0"
      :percentage="uploadProgress"
      status="success"
      style="margin-top: 20px"
    />
  </el-card>
</template>

3️⃣ 脚本逻辑(切片、上传、断点续传)

ts 复制代码
<script setup>
import { ref } from 'vue'
import SparkMD5 from 'spark-md5'
import { ElMessage } from 'element-plus'

const uploadProgress = ref(0)
const CHUNK_SIZE = 2 * 1024 * 1024 // 2MB

let file = null
let fileHash = ''
let fileChunks = []

// 1. 预处理文件
const handleBeforeUpload = async (rawFile) => {
  file = rawFile
  fileChunks = createChunks(file)
  fileHash = await calculateHash(fileChunks)
  return false // 阻止默认上传
}

// 2. 分片
const createChunks = (file) => {
  const chunks = []
  let cur = 0
  while (cur < file.size) {
    chunks.push(file.slice(cur, cur + CHUNK_SIZE))
    cur += CHUNK_SIZE
  }
  return chunks
}

// 3. 计算 hash
const calculateHash = (chunks) => {
  return new Promise((resolve) => {
    const spark = new SparkMD5.ArrayBuffer()
    let count = 0
    const reader = new FileReader()

    const loadNext = () => {
      if (count >= chunks.length) {
        resolve(spark.end())
        return
      }
      reader.readAsArrayBuffer(chunks[count])
    }

    reader.onload = (e) => {
      spark.append(e.target.result)
      count++
      loadNext()
    }

    loadNext()
  })
}

// 4. 获取已上传切片(断点续传)
const getUploadedList = async (hash) => {
  const res = await fetch(`/uploaded-list?hash=${hash}`)
  return res.ok ? await res.json() : []
}

// 5. 上传逻辑
const handleUpload = async () => {
  const uploaded = await getUploadedList(fileHash)

  const uploadChunk = (chunk, index) => {
    const form = new FormData()
    form.append('file', chunk)
    form.append('filename', file.name)
    form.append('chunkIndex', index)
    form.append('hash', fileHash)

    return fetch('/upload-chunk', {
      method: 'POST',
      body: form,
    })
  }

  const requests = fileChunks.map((chunk, index) => {
    if (uploaded.includes(index)) return null
    return uploadChunk(chunk, index)
  }).filter(Boolean)

  let completed = uploaded.length
  const total = fileChunks.length

  for (const req of requests) {
    await req
    completed++
    uploadProgress.value = Math.floor((completed / total) * 100)
  }

  // 通知合并
  await fetch('/merge-chunks', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ filename: file.name, hash: fileHash }),
  })

  ElMessage.success('上传成功 🎉')
  uploadProgress.value = 0
}
</script>

📡四、服务端接口规范(参考 Node)

接口说明:

接口 描述
GET /uploaded-list?hash=xxx 返回已上传切片 index 列表
POST /upload-chunk 接收切片文件,保存到 /tmp/hash/index
POST /merge-chunks 合并切片为完整文件,保存在 /uploads/

服务端可用 fs-extramulter 等处理上传,你需要支持以下流程:

  • 创建临时目录保存切片 /tmp/<hash>/index
  • 按顺序读取切片合并 fs.appendFileSync
  • 合并完成后清理切片

如果你需要我帮你写 Node.js 服务端的完整代码,也可以直接告诉我 👍


🧠五、总结回顾

功能 实现点
切片上传 Blob.slice() 分片,前端循环上传
秒传 前端计算 hash,服务端校验是否上传过
断点续传 获取已上传列表,跳过上传
合并通知 上传完毕后请求服务端合并接口
UI 展示 Element Plus 上传组件 + 进度条反馈
相关推荐
excel10 分钟前
JavaScript 中 WeakMap、WeakSet、Set、Map、Object、Array 的区别与应用场景
前端
haaaaaaarry1 小时前
Element Plus常见基础组件(一)
java·前端·javascript·vue.js
qingyingWin1 小时前
原生微信小程序研发,如何对图片进行统一管理?
前端·微信小程序
不懂英语的程序猿1 小时前
【JEECG】JVxeTable表格拖拽排序功能
前端·后端
拾光拾趣录1 小时前
前端灵魂拷问:从URL到Redux,17个常见问题
前端·面试
萌萌哒草头将军1 小时前
Prisma ORM 又双叒叕发布新版本了!🚀🚀🚀
前端·javascript·node.js
mldong2 小时前
推荐一款超高颜值的后台管理模板!Art-Design-Pro!开源!免费!
前端·vue.js·架构
草字2 小时前
uniapp 如果进入页面输入框自动聚焦,此时快速返回页面或者跳转到下一个页面,输入法顶上来的页面出现半屏的黑屏问题。
java·前端·uni-app
我是ed.2 小时前
cocos Js 使用 webview 通过 postMessage 进行通信
开发语言·javascript·ecmascript
程序视点2 小时前
Wise Duplicate Finder 重复文件查找工具 - 永久免费专业版文件去重工具
前端·windows