vue实现文件上传思路
Vue 文件上传实现思路
使用原生 HTML5 文件上传
通过 <input type="file"> 元素结合 Vue 的数据绑定和事件处理实现基础文件上传功能。
<template>
<div>
<input type="file" @change="handleFileChange" />
<button @click="uploadFile">上传</button>
</div>
</template>
<script>
export default {
data() {
return {
selectedFile: null
}
},
methods: {
handleFileChange(event) {
this.selectedFile = event.target.files[0]
},
uploadFile() {
if (!this.selectedFile) return
const formData = new FormData()
formData.append('file', this.selectedFile)
axios.post('/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
}).then(response => {
console.log('上传成功', response)
}).catch(error => {
console.error('上传失败', error)
})
}
}
}
</script>
使用第三方组件库
Element UI 或 Ant Design Vue 等 UI 库提供现成的上传组件,简化开发流程。
<template>
<el-upload
action="/upload"
:on-success="handleSuccess"
:on-error="handleError"
:before-upload="beforeUpload">
<el-button size="small" 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(response) {
this.$message.success('上传成功')
},
handleError() {
this.$message.error('上传失败')
}
}
}
</script>
分片上传实现
对于大文件上传,可采用分片上传技术提高可靠性和用户体验。
async function chunkUpload(file) {
const chunkSize = 2 * 1024 * 1024 // 2MB
const chunks = Math.ceil(file.size / chunkSize)
const md5 = await calculateMD5(file) // 计算文件唯一标识
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('fileMd5', md5)
await axios.post('/upload/chunk', formData)
}
// 通知服务器合并分片
await axios.post('/upload/merge', {
fileName: file.name,
fileMd5: md5,
totalChunks: chunks
})
}
拖拽上传实现
通过 HTML5 拖放 API 实现更友好的拖拽上传体验。
<template>
<div
class="drop-area"
@dragover.prevent="dragover"
@dragleave.prevent="dragleave"
@drop.prevent="drop">
<p>将文件拖拽到此处上传</p>
<input type="file" @change="handleFileChange" />
</div>
</template>
<script>
export default {
methods: {
dragover(event) {
event.currentTarget.classList.add('dragover')
},
dragleave(event) {
event.currentTarget.classList.remove('dragover')
},
drop(event) {
event.currentTarget.classList.remove('dragover')
this.selectedFile = event.dataTransfer.files[0]
this.uploadFile()
}
}
}
</script>
<style>
.drop-area {
border: 2px dashed #ccc;
padding: 20px;
text-align: center;
}
.dragover {
border-color: #409eff;
background-color: #f5f7fa;
}
</style>
进度显示实现
通过 XMLHttpRequest 或 axios 的 onUploadProgress 回调实现上传进度显示。
uploadFile() {
const config = {
onUploadProgress: progressEvent => {
const percentCompleted = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
)
this.progress = percentCompleted
}
}
axios.post('/upload', formData, config)
}
文件类型和大小验证
在上传前对文件进行验证,确保符合业务要求。
beforeUpload(file) {
const allowedTypes = ['image/jpeg', 'image/png', 'application/pdf']
const isAllowedType = allowedTypes.includes(file.type)
const isLt5M = file.size / 1024 / 1024 < 5
if (!isAllowedType) {
this.$message.error('只能上传 JPG/PNG/PDF 文件!')
return false
}
if (!isLt5M) {
this.$message.error('文件大小不能超过 5MB!')
return false
}
return true
}






