vue实现拖拽上传文件
Vue 拖拽上传文件实现方法
使用 HTML5 拖拽 API 和 Vue 事件绑定
在 Vue 组件中监听 dragover 和 drop 事件,阻止默认行为并处理文件上传逻辑。
<template>
<div
class="drop-area"
@dragover.prevent="handleDragOver"
@drop.prevent="handleDrop"
>
<p>拖拽文件到此处上传</p>
<input type="file" @change="handleFileSelect" multiple />
</div>
</template>
<script>
export default {
methods: {
handleDragOver(event) {
event.currentTarget.classList.add('dragover')
},
handleDrop(event) {
event.currentTarget.classList.remove('dragover')
const files = event.dataTransfer.files
this.uploadFiles(files)
},
handleFileSelect(event) {
const files = event.target.files
this.uploadFiles(files)
},
uploadFiles(files) {
// 实现上传逻辑
console.log(files)
}
}
}
</script>
<style>
.drop-area {
border: 2px dashed #ccc;
padding: 20px;
text-align: center;
}
.drop-area.dragover {
border-color: #42b983;
background-color: #f0f8ff;
}
</style>
使用第三方库 vue-drag-drop
安装 vue-drag-drop 库可以简化拖拽上传的实现。
npm install vue-drag-drop
在组件中使用:
<template>
<div class="container">
<drop-zone @files-dropped="handleFiles">
<p>拖拽文件到此处上传</p>
</drop-zone>
</div>
</template>
<script>
import { DropZone } from 'vue-drag-drop'
export default {
components: {
DropZone
},
methods: {
handleFiles(files) {
// 处理上传逻辑
console.log(files)
}
}
}
</script>
实现文件预览功能
在拖拽上传时添加文件预览功能可以提升用户体验。
<template>
<div>
<div
class="drop-area"
@dragover.prevent
@drop.prevent="handleDrop"
>
<p>拖拽文件到此处上传</p>
</div>
<div v-if="previews.length" class="previews">
<div v-for="(preview, index) in previews" :key="index">
<img v-if="preview.type.startsWith('image/')" :src="preview.url" width="100">
<div v-else>{{ preview.name }}</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
previews: []
}
},
methods: {
handleDrop(event) {
const files = event.dataTransfer.files
this.generatePreviews(files)
},
generatePreviews(files) {
this.previews = []
Array.from(files).forEach(file => {
const reader = new FileReader()
reader.onload = (e) => {
this.previews.push({
name: file.name,
type: file.type,
url: e.target.result
})
}
if (file.type.startsWith('image/')) {
reader.readAsDataURL(file)
} else {
this.previews.push({
name: file.name,
type: file.type
})
}
})
}
}
}
</script>
使用 axios 实现文件上传
结合 axios 可以实现完整的文件上传功能。
methods: {
async uploadFiles(files) {
const formData = new FormData()
Array.from(files).forEach(file => {
formData.append('files[]', 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)
}
}
}
添加进度条功能
上传大文件时显示进度条可以提升用户体验。
<template>
<div>
<progress v-if="uploadProgress > 0" :value="uploadProgress" max="100"></progress>
</div>
</template>
<script>
export default {
data() {
return {
uploadProgress: 0
}
},
methods: {
async uploadFiles(files) {
const formData = new FormData()
Array.from(files).forEach(file => {
formData.append('files[]', file)
})
try {
const response = await axios.post('/api/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
},
onUploadProgress: progressEvent => {
this.uploadProgress = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
)
}
})
this.uploadProgress = 0
console.log('上传成功', response.data)
} catch (error) {
this.uploadProgress = 0
console.error('上传失败', error)
}
}
}
}
</script>






