vue 实现上传视频
使用 Vue 实现上传视频功能
在 Vue 中实现上传视频功能,通常需要结合 HTML 的 <input type="file"> 元素和 Vue 的事件处理。以下是具体实现方法:
基本文件上传实现
创建一个文件上传组件,允许用户选择视频文件并上传:
<template>
<div>
<input type="file" accept="video/*" @change="handleFileUpload" />
<button @click="uploadVideo">上传视频</button>
<p v-if="uploadProgress">{{ uploadProgress }}%</p>
<p v-if="errorMessage" style="color: red">{{ errorMessage }}</p>
</div>
</template>
<script>
export default {
data() {
return {
selectedFile: null,
uploadProgress: 0,
errorMessage: ''
}
},
methods: {
handleFileUpload(event) {
const file = event.target.files[0]
if (file && file.type.includes('video')) {
this.selectedFile = file
this.errorMessage = ''
} else {
this.errorMessage = '请选择有效的视频文件'
}
},
async uploadVideo() {
if (!this.selectedFile) {
this.errorMessage = '请先选择视频文件'
return
}
const formData = new FormData()
formData.append('video', this.selectedFile)
try {
const response = await axios.post('/api/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
},
onUploadProgress: progressEvent => {
this.uploadProgress = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
)
}
})
console.log('上传成功:', response.data)
} catch (error) {
this.errorMessage = '上传失败: ' + error.message
}
}
}
}
</script>
视频预览功能
在上传前显示视频预览:

<template>
<div>
<input type="file" accept="video/*" @change="handleFileUpload" />
<video v-if="videoUrl" :src="videoUrl" controls width="300"></video>
<button @click="uploadVideo">上传视频</button>
</div>
</template>
<script>
export default {
data() {
return {
selectedFile: null,
videoUrl: ''
}
},
methods: {
handleFileUpload(event) {
const file = event.target.files[0]
if (file && file.type.includes('video')) {
this.selectedFile = file
this.videoUrl = URL.createObjectURL(file)
}
}
}
}
</script>
文件大小和类型验证
添加文件验证逻辑:
methods: {
handleFileUpload(event) {
const file = event.target.files[0]
const maxSize = 100 * 1024 * 1024 // 100MB
const allowedTypes = ['video/mp4', 'video/webm', 'video/ogg']
if (!file) return
if (!allowedTypes.includes(file.type)) {
this.errorMessage = '不支持的视频格式'
return
}
if (file.size > maxSize) {
this.errorMessage = '视频文件不能超过100MB'
return
}
this.selectedFile = file
this.errorMessage = ''
}
}
分块上传大文件
对于大文件,可以实现分块上传:

async uploadVideo() {
const chunkSize = 5 * 1024 * 1024 // 5MB
const chunks = Math.ceil(this.selectedFile.size / chunkSize)
for (let i = 0; i < chunks; i++) {
const start = i * chunkSize
const end = Math.min(start + chunkSize, this.selectedFile.size)
const chunk = this.selectedFile.slice(start, end)
const formData = new FormData()
formData.append('chunk', chunk)
formData.append('chunkIndex', i)
formData.append('totalChunks', chunks)
formData.append('fileName', this.selectedFile.name)
try {
await axios.post('/api/upload-chunk', formData)
this.uploadProgress = Math.round(((i + 1) / chunks) * 100)
} catch (error) {
this.errorMessage = `分块上传失败: ${error.message}`
return
}
}
// 所有分块上传完成后通知服务器合并
await axios.post('/api/merge-chunks', {
fileName: this.selectedFile.name,
totalChunks: chunks
})
}
使用第三方库
可以使用 vue-dropzone 等第三方库简化实现:
import vue2Dropzone from 'vue2-dropzone'
import 'vue2-dropzone/dist/vue2Dropzone.min.css'
export default {
components: {
vueDropzone: vue2Dropzone
},
data() {
return {
dropzoneOptions: {
url: '/api/upload',
acceptedFiles: 'video/*',
maxFilesize: 100, // MB
addRemoveLinks: true,
dictDefaultMessage: '拖放视频文件或点击上传'
}
}
}
}
<template>
<vue-dropzone id="dropzone" :options="dropzoneOptions"></vue-dropzone>
</template>
服务器端处理
在 Node.js 服务器端处理上传的示例:
const express = require('express')
const multer = require('multer')
const upload = multer({ dest: 'uploads/' })
app.post('/api/upload', upload.single('video'), (req, res) => {
// req.file 包含上传的文件信息
res.json({ message: '上传成功', file: req.file })
})
以上方法提供了从简单到复杂的视频上传实现方案,可以根据项目需求选择合适的实现方式。






