vue实现附件组件
Vue 实现附件组件的方法
基础组件结构
使用 Vue 的单文件组件(SFC)方式创建一个基础的附件上传组件。需要包含文件选择、预览、上传和删除功能。
<template>
<div class="attachment-component">
<input type="file" @change="handleFileChange" multiple />
<div v-for="(file, index) in files" :key="index" class="file-item">
<span>{{ file.name }}</span>
<button @click="removeFile(index)">删除</button>
</div>
<button @click="uploadFiles">上传</button>
</div>
</template>
<script>
export default {
data() {
return {
files: []
}
},
methods: {
handleFileChange(event) {
this.files = Array.from(event.target.files)
},
removeFile(index) {
this.files.splice(index, 1)
},
uploadFiles() {
// 上传逻辑
}
}
}
</script>
文件预览功能
对于图片类型的附件,可以添加预览功能。使用 URL.createObjectURL 生成临时链接显示预览。
<template>
<div v-for="(file, index) in files" :key="index">
<img v-if="file.type.startsWith('image/')" :src="getPreview(file)" width="100" />
<span>{{ file.name }}</span>
</div>
</template>
<script>
methods: {
getPreview(file) {
return URL.createObjectURL(file)
},
beforeDestroy() {
this.files.forEach(file => {
URL.revokeObjectURL(this.getPreview(file))
})
}
}
</script>
上传功能实现
使用 axios 或其他 HTTP 客户端实现文件上传功能。需要构建 FormData 对象发送文件数据。

methods: {
async uploadFiles() {
const formData = new FormData()
this.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)
}
}
}
进度显示
添加上传进度显示功能,通过 axios 的 onUploadProgress 回调更新进度条。
<template>
<div v-if="uploading">
上传进度: {{ progress }}%
<progress :value="progress" max="100"></progress>
</div>
</template>
<script>
data() {
return {
uploading: false,
progress: 0
}
},
methods: {
async uploadFiles() {
this.uploading = true
try {
await axios.post('/api/upload', formData, {
onUploadProgress: progressEvent => {
this.progress = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
)
}
})
} finally {
this.uploading = false
}
}
}
</script>
文件限制
添加文件类型和大小限制,在上传前进行验证。

methods: {
handleFileChange(event) {
const files = Array.from(event.target.files)
const validFiles = files.filter(file => {
const isValidType = ['image/jpeg', 'image/png'].includes(file.type)
const isValidSize = file.size < 2 * 1024 * 1024 // 2MB
return isValidType && isValidSize
})
this.files = validFiles
}
}
拖放上传
实现拖放文件上传功能,提升用户体验。
<template>
<div
class="drop-zone"
@dragover.prevent="dragover"
@dragleave.prevent="dragleave"
@drop.prevent="drop"
:class="{ 'drag-active': isDragActive }"
>
拖放文件到这里
</div>
</template>
<script>
data() {
return {
isDragActive: false
}
},
methods: {
dragover() {
this.isDragActive = true
},
dragleave() {
this.isDragActive = false
},
drop(event) {
this.isDragActive = false
this.handleFileChange(event)
}
}
</script>
组件封装
将组件封装为可复用的形式,通过 props 接收配置参数,通过 emits 触发事件。
<script>
export default {
props: {
maxSize: {
type: Number,
default: 2 * 1024 * 1024
},
allowedTypes: {
type: Array,
default: () => ['image/jpeg', 'image/png']
}
},
emits: ['upload-success', 'upload-error'],
methods: {
async uploadFiles() {
try {
const response = await axios.post('/api/upload', formData)
this.$emit('upload-success', response.data)
} catch (error) {
this.$emit('upload-error', error)
}
}
}
}
</script>






