vue实现上传文件案例
Vue 文件上传实现方法
基础表单上传
使用原生 <input type="file"> 结合 FormData 实现文件上传:
<template>
<div>
<input type="file" @change="handleFileChange" />
<button @click="uploadFile">上传</button>
</div>
</template>
<script>
export default {
methods: {
handleFileChange(e) {
this.file = e.target.files[0]
},
async uploadFile() {
const formData = new FormData()
formData.append('file', this.file)
try {
const res = await axios.post('/api/upload', formData, {
headers: { 'Content-Type': 'multipart/form-data' }
})
console.log('上传成功', res.data)
} catch (error) {
console.error('上传失败', error)
}
}
}
}
</script>
使用第三方组件
推荐使用 vue-upload-component 或 element-ui 的上传组件:
Element UI 示例:
<template>
<el-upload
action="/api/upload"
:on-success="handleSuccess"
:before-upload="beforeUpload">
<el-button type="primary">点击上传</el-button>
</el-upload>
</template>
<script>
export default {
methods: {
beforeUpload(file) {
const isLt2M = file.size / 1024 / 1024 < 2
if (!isLt2M) {
this.$message.error('文件大小不能超过2MB')
}
return isLt2M
},
handleSuccess(res) {
console.log('上传成功', res)
}
}
}
</script>
拖拽上传实现
通过 HTML5 拖拽 API 实现更友好的交互:
<template>
<div
class="drop-area"
@dragover.prevent="dragover"
@dragleave.prevent="dragleave"
@drop.prevent="drop">
{{ dropText }}
<input type="file" @change="handleFileChange" hidden ref="fileInput"/>
</div>
</template>
<script>
export default {
data() {
return {
dropText: '拖拽文件到此处或点击选择',
isDragging: false
}
},
methods: {
dragover() {
this.isDragging = true
this.dropText = '释放文件以上传'
},
dragleave() {
this.isDragging = false
this.dropText = '拖拽文件到此处或点击选择'
},
drop(e) {
this.isDragging = false
this.file = e.dataTransfer.files[0]
this.uploadFile()
}
}
}
</script>
<style>
.drop-area {
border: 2px dashed #ccc;
padding: 20px;
text-align: center;
}
</style>
大文件分片上传
对于大文件可采用分片上传策略:
async function chunkUpload(file) {
const chunkSize = 2 * 1024 * 1024 // 2MB
const chunks = Math.ceil(file.size / chunkSize)
const md5 = await calculateMD5(file) // 需要实现MD5计算
for (let i = 0; i < chunks; i++) {
const start = i * chunkSize
const end = Math.min(file.size, start + chunkSize)
const chunk = file.slice(start, end)
const formData = new FormData()
formData.append('chunk', chunk)
formData.append('chunkIndex', i)
formData.append('totalChunks', chunks)
formData.append('identifier', md5)
await axios.post('/api/chunk-upload', formData)
}
// 通知服务器合并分片
await axios.post('/api/merge', {
filename: file.name,
identifier: md5,
totalChunks: chunks
})
}
进度显示实现
通过 axios 的 onUploadProgress 回调显示上传进度:
uploadFile() {
const config = {
onUploadProgress: progressEvent => {
const percent = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
)
console.log(`上传进度: ${percent}%`)
}
}
axios.post('/api/upload', formData, config)
}
注意事项
- 服务器需配置
multipart/form-data支持 - 生产环境应添加文件类型、大小验证
- 敏感文件应在前端加密后再上传
- 考虑断点续传功能优化用户体验
- 跨域上传需要配置 CORS 策略







