vue实现前端提交文件
文件上传基础实现
使用Vue结合HTML5的<input type="file">元素实现基础文件上传:
<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('/api/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
}).then(response => {
console.log('上传成功', response.data)
}).catch(error => {
console.error('上传失败', error)
})
}
}
}
</script>
多文件上传支持
修改文件选择处理逻辑以支持多文件选择:
handleFileChange(event) {
this.selectedFiles = Array.from(event.target.files)
},
uploadFiles() {
const formData = new FormData()
this.selectedFiles.forEach(file => {
formData.append('files[]', file)
})
axios.post('/api/multi-upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
}
文件预览与验证
在上传前添加文件预览和验证逻辑:
handleFileChange(event) {
const file = event.target.files[0]
if (!file) return
// 文件类型验证
const allowedTypes = ['image/jpeg', 'image/png']
if (!allowedTypes.includes(file.type)) {
alert('仅支持JPEG/PNG格式图片')
return
}
// 文件大小限制(2MB)
const maxSize = 2 * 1024 * 1024
if (file.size > maxSize) {
alert('文件大小不能超过2MB')
return
}
// 图片预览
const reader = new FileReader()
reader.onload = (e) => {
this.previewUrl = e.target.result
}
reader.readAsDataURL(file)
this.selectedFile = file
}
进度显示与取消上传
添加上传进度监控和取消功能:
data() {
return {
uploadProgress: 0,
cancelToken: null
}
},
methods: {
uploadFile() {
const CancelToken = axios.CancelToken
const source = CancelToken.source()
this.cancelToken = source
axios.post('/api/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
},
onUploadProgress: progressEvent => {
this.uploadProgress = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
)
},
cancelToken: source.token
})
},
cancelUpload() {
if (this.cancelToken) {
this.cancelToken.cancel('用户取消上传')
}
}
}
使用第三方组件库
使用Element UI的上传组件示例:
<template>
<el-upload
action="/api/upload"
:on-success="handleSuccess"
:on-error="handleError"
:before-upload="beforeUpload"
:file-list="fileList"
:auto-upload="false"
:limit="3"
:on-exceed="handleExceed"
multiple>
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
</el-upload>
</template>
<script>
export default {
data() {
return {
fileList: []
}
},
methods: {
beforeUpload(file) {
const isImage = file.type.includes('image/')
const isLt500K = file.size / 1024 < 500
if (!isImage) {
this.$message.error('只能上传图片文件!')
}
if (!isLt500K) {
this.$message.error('图片大小不能超过500KB!')
}
return isImage && isLt500K
},
handleSuccess(response, file) {
this.$message.success('上传成功')
},
handleError(err, file) {
this.$message.error('上传失败')
},
handleExceed(files, fileList) {
this.$message.warning('最多只能上传3个文件')
}
}
}
</script>
大文件分片上传
实现大文件分片上传逻辑:
async uploadLargeFile(file) {
const chunkSize = 2 * 1024 * 1024 // 2MB每片
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)
try {
await axios.post('/api/chunk-upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
this.uploadProgress = Math.round(((i + 1) / chunks) * 100)
} catch (error) {
console.error('分片上传失败', error)
break
}
}
// 所有分片上传完成后通知服务器合并
axios.post('/api/merge-chunks', {
fileMd5,
fileName: file.name,
totalChunks: chunks
})
}






