vue实现多文件上传
使用 Vue 实现多文件上传
使用原生 HTML5 文件上传
创建一个包含 input 元素的组件,设置 multiple 属性以支持多文件选择:
<template>
<div>
<input type="file" multiple @change="handleFileChange" />
<button @click="uploadFiles">上传</button>
</div>
</template>
<script>
export default {
data() {
return {
files: []
}
},
methods: {
handleFileChange(event) {
this.files = Array.from(event.target.files)
},
uploadFiles() {
const formData = new FormData()
this.files.forEach(file => {
formData.append('files', file)
})
// 使用 axios 或其他 HTTP 客户端上传
axios.post('/api/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
}).then(response => {
console.log('上传成功', response)
})
}
}
}
</script>
使用第三方库 vue-upload-component
安装 vue-upload-component:

npm install vue-upload-component
在组件中使用:
<template>
<div>
<file-upload
multiple
:maximum="10"
@input="handleFiles"
:headers="{'X-CSRF-TOKEN': token}"
:url="'/api/upload'"
></file-upload>
</div>
</template>
<script>
import FileUpload from 'vue-upload-component'
export default {
components: {
FileUpload
},
data() {
return {
token: document.querySelector('meta[name="csrf-token"]').content
}
},
methods: {
handleFiles(files) {
console.log('已选择文件', files)
}
}
}
</script>
实现拖拽上传
添加拖拽区域和事件处理:

<template>
<div
class="drop-zone"
@dragover.prevent="dragover"
@dragleave.prevent="dragleave"
@drop.prevent="drop"
>
<p>拖拽文件到此处上传</p>
<input type="file" multiple @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.files = Array.from(event.dataTransfer.files)
}
}
}
</script>
<style>
.drop-zone {
border: 2px dashed #ccc;
padding: 20px;
text-align: center;
}
.drop-zone.dragover {
border-color: #42b983;
}
</style>
上传进度显示
使用 axios 的 onUploadProgress 回调显示上传进度:
<template>
<div>
<input type="file" multiple @change="handleFileChange" />
<button @click="uploadFiles">上传</button>
<div v-if="progress > 0">
上传进度: {{ progress }}%
</div>
</div>
</template>
<script>
export default {
data() {
return {
progress: 0
}
},
methods: {
uploadFiles() {
const formData = new FormData()
this.files.forEach(file => {
formData.append('files', file)
})
axios.post('/api/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
},
onUploadProgress: progressEvent => {
this.progress = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
)
}
})
}
}
}
</script>
文件预览和限制
在文件选择后显示预览和文件信息:
<template>
<div>
<input type="file" multiple @change="handleFileChange" accept="image/*,.pdf" />
<div v-for="(file, index) in files" :key="index">
<p>{{ file.name }} ({{ formatSize(file.size) }})</p>
<img v-if="file.type.includes('image')" :src="getPreview(file)" width="100" />
</div>
</div>
</template>
<script>
export default {
methods: {
handleFileChange(event) {
const files = Array.from(event.target.files)
// 限制文件大小
this.files = files.filter(file => file.size < 5 * 1024 * 1024)
},
getPreview(file) {
return URL.createObjectURL(file)
},
formatSize(bytes) {
if (bytes === 0) return '0 Bytes'
const k = 1024
const sizes = ['Bytes', 'KB', 'MB', 'GB']
const i = Math.floor(Math.log(bytes) / Math.log(k))
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}
}
}
</script>
这些方法提供了从基础到进阶的多文件上传实现方案,可以根据项目需求选择适合的方式或组合使用。






