当前位置:首页 > VUE

vue实现分段上传

2026-03-28 06:20:16VUE

分段上传的实现原理

分段上传(Chunked Upload)是将大文件分割成多个小块分别上传,最后在服务端合并的技术。这种方式能有效解决大文件上传超时、网络不稳定等问题,同时支持断点续传和进度显示。

前端实现步骤

安装必要的依赖库(如axios):

npm install axios

创建文件分片函数:

function createFileChunks(file, chunkSize = 5 * 1024 * 1024) {
  const chunks = []
  let start = 0
  while (start < file.size) {
    chunks.push({
      file: file.slice(start, start + chunkSize),
      filename: file.name
    })
    start += chunkSize
  }
  return chunks
}

上传组件示例:

<template>
  <input type="file" @change="handleFileChange" />
  <button @click="uploadFile">上传</button>
  <div>进度:{{ progress }}%</div>
</template>

<script>
import axios from 'axios'

export default {
  data() {
    return {
      file: null,
      progress: 0
    }
  },
  methods: {
    handleFileChange(e) {
      this.file = e.target.files[0]
    },
    async uploadFile() {
      if (!this.file) return

      const chunks = createFileChunks(this.file)
      const total = chunks.length
      const uploads = chunks.map((chunk, index) => {
        const formData = new FormData()
        formData.append('file', chunk.file)
        formData.append('filename', chunk.filename)
        formData.append('chunkIndex', index)
        formData.append('totalChunks', total)

        return axios.post('/upload', formData, {
          onUploadProgress: (progressEvent) => {
            const percent = Math.round(
              (progressEvent.loaded / progressEvent.total) * 100
            )
            this.progress = Math.min(
              100,
              ((index * 100) + percent) / total
            )
          }
        })
      })

      await Promise.all(uploads)
      await axios.post('/merge', {
        filename: this.file.name,
        totalChunks: total
      })
    }
  }
}
</script>

服务端处理要点

Node.js 示例(使用Express):

const express = require('express')
const multer = require('multer')
const fs = require('fs')
const path = require('path')

const app = express()
const upload = multer({ dest: 'temp/' })

app.post('/upload', upload.single('file'), (req, res) => {
  const { filename, chunkIndex } = req.body
  const tempPath = path.join('temp', `${filename}-${chunkIndex}`)
  fs.renameSync(req.file.path, tempPath)
  res.send({ success: true })
})

app.post('/merge', (req, res) => {
  const { filename, totalChunks } = req.body
  const writeStream = fs.createWriteStream(`uploads/${filename}`)

  for (let i = 0; i < totalChunks; i++) {
    const chunkPath = path.join('temp', `${filename}-${i}`)
    const chunk = fs.readFileSync(chunkPath)
    writeStream.write(chunk)
    fs.unlinkSync(chunkPath)
  }

  writeStream.end()
  res.send({ success: true })
})

app.listen(3000)

优化建议

实现文件哈希校验可以在分片前计算文件唯一标识,避免重复上传。使用Web Worker处理大文件计算防止UI阻塞。

添加断点续传功能需要服务端支持查询已上传分片,前端根据返回结果跳过已上传部分。典型做法是在分片上传前先发送查询请求。

vue实现分段上传

进度显示优化可以考虑分片进度和整体进度分开显示,使用更直观的进度条组件替代简单百分比。

标签: 上传vue
分享给朋友:

相关文章

vue实现muli

vue实现muli

Vue 实现多语言(i18n)支持 在 Vue 项目中实现多语言(i18n)功能,通常使用 vue-i18n 插件。以下是具体实现步骤: 安装 vue-i18n npm install vue-i…

vue原理实现

vue原理实现

Vue 原理实现的核心机制 Vue.js 的核心原理基于响应式系统、虚拟 DOM 和模板编译。以下是其核心实现机制的分解: 响应式系统 Vue 使用 Object.defineProperty(Vu…

vue监听实现

vue监听实现

Vue 监听实现方法 在 Vue 中可以通过多种方式实现监听数据变化或事件触发,以下是常见的几种方法: 使用 watch 选项 watch 是 Vue 提供的核心功能之一,用于观察和响应 Vue 实…

vue实现 hover

vue实现 hover

实现 Vue 中的 hover 效果 在 Vue 中实现 hover 效果可以通过多种方式完成,以下是常见的几种方法: 使用 CSS 伪类 最简单的方式是直接使用 CSS 的 :hover 伪类,无…

vue 实现评分

vue 实现评分

Vue 实现评分功能 在 Vue 中实现评分功能可以通过多种方式完成,包括使用第三方组件库或自定义实现。以下是两种常见的方法: 使用第三方组件库(如 Element UI) Element UI 提…

vue 实现图钉

vue 实现图钉

实现图钉效果的步骤 在Vue中实现图钉(固定位置)效果,可以通过CSS的position: sticky属性或监听滚动事件动态修改元素样式。以下是两种常见方法: 方法一:使用CSS的position…