vue上传文档怎么实现
文件上传基础实现
使用Vue结合HTML的<input type="file">元素实现基础文件上传功能。通过@change事件监听文件选择,获取文件对象后可通过FormData发送到服务器。
<template>
<div>
<input type="file" @change="handleFileUpload" />
<button @click="submitFile">上传</button>
</div>
</template>
<script>
export default {
data() {
return {
file: null
}
},
methods: {
handleFileUpload(event) {
this.file = event.target.files[0]
},
async submitFile() {
const formData = new FormData()
formData.append('file', this.file)
try {
const response = await axios.post('/api/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
console.log('上传成功', response.data)
} catch (error) {
console.error('上传失败', error)
}
}
}
}
</script>
使用第三方组件库
Element UI或Ant Design Vue等UI库提供现成的上传组件,简化开发流程。以Element UI为例:

<template>
<el-upload
action="/api/upload"
:on-success="handleSuccess"
:on-error="handleError"
:before-upload="beforeUpload">
<el-button type="primary">点击上传</el-button>
</el-upload>
</template>
<script>
export default {
methods: {
beforeUpload(file) {
const isLt10M = file.size / 1024 / 1024 < 10
if (!isLt10M) {
this.$message.error('文件大小不能超过10MB')
return false
}
return true
},
handleSuccess(response) {
console.log('上传成功', response)
},
handleError(err) {
console.error('上传失败', err)
}
}
}
</script>
多文件上传处理
通过设置HTML输入框的multiple属性实现多文件选择,遍历文件列表逐个添加到FormData中。
<template>
<div>
<input type="file" multiple @change="handleFilesUpload" />
<button @click="uploadFiles">批量上传</button>
</div>
</template>
<script>
export default {
data() {
return {
files: []
}
},
methods: {
handleFilesUpload(event) {
this.files = Array.from(event.target.files)
},
async uploadFiles() {
const formData = new FormData()
this.files.forEach(file => {
formData.append('files[]', file)
})
try {
const response = await axios.post('/api/multi-upload', formData)
console.log('批量上传成功', response.data)
} catch (error) {
console.error('上传失败', error)
}
}
}
}
</script>
进度显示实现
利用axios的onUploadProgress回调函数实现上传进度显示,配合UI组件展示进度条。

<template>
<div>
<input type="file" @change="setFile" />
<button @click="uploadWithProgress">上传</button>
<div v-if="progressVisible">
进度: {{ progress }}%
<el-progress :percentage="progress"></el-progress>
</div>
</div>
</template>
<script>
export default {
data() {
return {
file: null,
progress: 0,
progressVisible: false
}
},
methods: {
setFile(event) {
this.file = event.target.files[0]
},
async uploadWithProgress() {
const formData = new FormData()
formData.append('file', this.file)
this.progressVisible = true
this.progress = 0
try {
await axios.post('/api/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
},
onUploadProgress: progressEvent => {
this.progress = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
)
}
})
this.$message.success('上传完成')
} catch (error) {
this.$message.error('上传失败')
} finally {
setTimeout(() => {
this.progressVisible = false
}, 2000)
}
}
}
}
</script>
文件类型限制
通过文件对象的type属性或扩展名验证,确保只允许上传特定格式的文件。
methods: {
beforeUpload(file) {
const allowedTypes = ['image/jpeg', 'image/png', 'application/pdf']
const isAllowed = allowedTypes.includes(file.type)
const extension = file.name.split('.').pop().toLowerCase()
const isExtensionValid = ['jpg', 'jpeg', 'png', 'pdf'].includes(extension)
if (!isAllowed || !isExtensionValid) {
this.$message.error('只能上传JPG/PNG/PDF文件')
return false
}
return true
}
}
大文件分片上传
针对大文件实现分片上传,提高上传成功率并支持断点续传。
async uploadLargeFile(file) {
const chunkSize = 5 * 1024 * 1024 // 5MB每片
const chunks = Math.ceil(file.size / chunkSize)
const fileMd5 = await this.calculateFileMd5(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('file', chunk)
formData.append('chunkIndex', i)
formData.append('totalChunks', chunks)
formData.append('fileMd5', fileMd5)
formData.append('fileName', file.name)
try {
await axios.post('/api/chunk-upload', formData)
console.log(`分片 ${i+1}/${chunks} 上传成功`)
} catch (error) {
console.error(`分片 ${i+1} 上传失败`, error)
throw error
}
}
// 所有分片上传完成后通知服务器合并
await axios.post('/api/merge-chunks', {
fileMd5,
fileName: file.name,
totalChunks: chunks
})
}






