vue实现视频上传管理
Vue 视频上传管理实现方案
前端部分(Vue.js)
文件选择与预览
使用 <input type="file"> 结合 Vue 的 v-on:change 事件监听文件选择
<template>
<input type="file" accept="video/*" @change="handleFileChange">
<video v-if="videoUrl" :src="videoUrl" controls width="300"></video>
</template>
<script>
export default {
data() {
return {
videoUrl: null
}
},
methods: {
handleFileChange(e) {
const file = e.target.files[0]
this.videoUrl = URL.createObjectURL(file)
}
}
}
</script>
分片上传实现 使用 axios 实现大文件分片上传

async uploadChunks(file) {
const chunkSize = 5 * 1024 * 1024 // 5MB
const chunks = Math.ceil(file.size / chunkSize)
const uploadId = Date.now().toString()
for (let i = 0; i < chunks; i++) {
const start = i * chunkSize
const end = Math.min(start + chunkSize, file.size)
const chunk = file.slice(start, end)
const formData = new FormData()
formData.append('chunk', chunk)
formData.append('chunkIndex', i)
formData.append('totalChunks', chunks)
formData.append('uploadId', uploadId)
formData.append('filename', file.name)
await axios.post('/api/upload', formData, {
headers: { 'Content-Type': 'multipart/form-data' }
})
}
}
后端部分(Node.js示例)
接收分片并合并
const fs = require('fs')
const path = require('path')
const multer = require('multer')
// 临时存储分片
const storage = multer.diskStorage({
destination: (req, file, cb) => {
const uploadId = req.body.uploadId
const dir = `./temp/${uploadId}`
fs.mkdirSync(dir, { recursive: true })
cb(null, dir)
},
filename: (req, file, cb) => {
cb(null, `${req.body.chunkIndex}`)
}
})
// 合并分片
app.post('/merge', (req, res) => {
const { uploadId, filename, totalChunks } = req.body
const dir = `./temp/${uploadId}`
const writeStream = fs.createWriteStream(`./uploads/${filename}`)
for (let i = 0; i < totalChunks; i++) {
const chunkPath = path.join(dir, i.toString())
const chunk = fs.readFileSync(chunkPath)
writeStream.write(chunk)
fs.unlinkSync(chunkPath)
}
writeStream.end()
fs.rmdirSync(dir)
res.send({ success: true })
})
视频管理功能
视频列表展示

<template>
<div v-for="video in videos" :key="video.id">
<video :src="video.url" controls width="300"></video>
<p>{{ video.name }}</p>
<button @click="deleteVideo(video.id)">删除</button>
</div>
</template>
<script>
export default {
data() {
return {
videos: []
}
},
mounted() {
this.fetchVideos()
},
methods: {
async fetchVideos() {
const res = await axios.get('/api/videos')
this.videos = res.data
},
async deleteVideo(id) {
await axios.delete(`/api/videos/${id}`)
this.fetchVideos()
}
}
}
</script>
进度显示与错误处理
上传进度条
axios.post('/api/upload', formData, {
headers: { 'Content-Type': 'multipart/form-data' },
onUploadProgress: progressEvent => {
const percent = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
)
this.uploadProgress = percent
}
})
错误处理机制
try {
await uploadChunks(file)
} catch (error) {
console.error('上传失败:', error)
this.uploadError = '上传失败,请重试'
if (error.response?.status === 413) {
this.uploadError = '文件过大,请选择小于2GB的视频'
}
}
优化建议
- 使用 Web Worker 处理大文件分片计算
- 实现断点续传功能,保存已上传分片信息
- 添加视频格式校验(MP4/WebM等)
- 实现视频封面自动生成功能
- 添加上传速度限制和并发控制






