FileUpload 文件上传
文件上传组件,支持多文件上传、拖拽上传、进度显示等功能。
基础用法
vue
<script setup lang="ts">
import { ref } from 'vue'
import { FileUpload } from '@vben/common-ui'
const fileList = ref<string[]>([])
</script>
<template>
<FileUpload v-model="fileList" />
</template>多文件上传
vue
<script setup lang="ts">
import { ref } from 'vue'
import { FileUpload } from '@vben/common-ui'
const fileList = ref<string[]>([])
</script>
<template>
<FileUpload
v-model="fileList"
:limit="10"
multiple
/>
</template>拖拽上传
vue
<script setup lang="ts">
import { ref } from 'vue'
import { FileUpload } from '@vben/common-ui'
const fileList = ref<string[]>([])
</script>
<template>
<FileUpload
v-model="fileList"
drag
>
<template #default>
<div class="upload-drag-area">
<p class="upload-drag-icon">📁</p>
<p class="upload-drag-text">将文件拖到此处,或点击上传</p>
</div>
</template>
</FileUpload>
</template>
<style scoped>
.upload-drag-area {
padding: 40px;
text-align: center;
}
.upload-drag-icon {
font-size: 48px;
margin-bottom: 16px;
}
.upload-drag-text {
color: #999;
}
</style>限制文件类型
vue
<script setup lang="ts">
import { ref } from 'vue'
import { FileUpload } from '@vben/common-ui'
const fileList = ref<string[]>([])
</script>
<template>
<FileUpload
v-model="fileList"
:accept="['.pdf', '.doc', '.docx', '.xls', '.xlsx']"
/>
</template>限制文件大小
vue
<script setup lang="ts">
import { ref } from 'vue'
import { FileUpload } from '@vben/common-ui'
const fileList = ref<string[]>([])
</script>
<template>
<FileUpload
v-model="fileList"
:max-size="10"
:on-exceed-size="handleExceedSize"
/>
</template>
<script setup lang="ts">
const handleExceedSize = (file: File) => {
message.error(`文件 ${file.name} 超过 10MB`)
}
</script>API
Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| modelValue | 绑定值 | string | string[] | - |
| multiple | 是否支持多选 | boolean | false |
| limit | 最大上传数量 | number | Infinity |
| maxSize | 文件大小限制(MB) | number | 100 |
| accept | 接受的文件类型 | string[] | [] |
| action | 上传地址 | string | /api/upload |
| headers | 上传请求头 | object | {} |
| data | 上传额外参数 | object | {} |
| drag | 是否启用拖拽上传 | boolean | false |
| disabled | 是否禁用 | boolean | false |
| showFileList | 是否显示文件列表 | boolean | true |
| autoUpload | 是否自动上传 | boolean | true |
Events
| 事件名 | 说明 | 回调参数 |
|---|---|---|
| update:modelValue | 值变化时触发 | (value: string | string[]) => void |
| change | 文件状态改变时触发 | (fileList: UploadFile[]) => void |
| success | 上传成功时触发 | (response: any, file: UploadFile) => void |
| error | 上传失败时触发 | (error: Error, file: UploadFile) => void |
| progress | 上传进度变化时触发 | (percent: number, file: UploadFile) => void |
| remove | 删除文件时触发 | (file: UploadFile) => void |
| exceed | 超过限制数量时触发 | (files: File[]) => void |
| exceedSize | 超过文件大小时触发 | (file: File) => void |
Slots
| 插槽名 | 说明 | 参数 |
|---|---|---|
| default | 自定义上传按钮 | - |
| tip | 自定义提示信息 | - |
| file | 自定义文件列表项 | { file: UploadFile } |
Methods
| 方法名 | 说明 | 参数 |
|---|---|---|
| submit | 手动上传 | - |
| clearFiles | 清空文件列表 | - |
| abort | 取消上传 | (file?: UploadFile) => void |
完整示例
vue
<script setup lang="ts">
import { ref } from 'vue'
import { message } from 'ant-design-vue'
import { FileUpload } from '@vben/common-ui'
import type { UploadFile } from 'ant-design-vue'
const fileList = ref<string[]>([])
const uploadRef = ref()
const handleSuccess = (response: any, file: UploadFile) => {
message.success(`${file.name} 上传成功`)
}
const handleError = (error: Error, file: UploadFile) => {
message.error(`${file.name} 上传失败:${error.message}`)
}
const handleProgress = (percent: number, file: UploadFile) => {
console.log(`${file.name} 上传进度:${percent}%`)
}
const handleRemove = (file: UploadFile) => {
console.log('删除文件:', file)
}
const handleExceed = (files: File[]) => {
message.warning(`最多只能上传 5 个文件,当前选择了 ${files.length} 个文件`)
}
const handleExceedSize = (file: File) => {
message.error(`文件 ${file.name} 超过 10MB`)
}
const handleSubmit = () => {
uploadRef.value?.submit()
}
const handleClear = () => {
uploadRef.value?.clearFiles()
}
</script>
<template>
<div>
<FileUpload
ref="uploadRef"
v-model="fileList"
multiple
drag
:limit="5"
:max-size="10"
:accept="['.pdf', '.doc', '.docx', '.xls', '.xlsx', '.zip']"
action="/api/upload/file"
:headers="{ Authorization: 'Bearer token' }"
:data="{ folder: 'documents' }"
:auto-upload="false"
@success="handleSuccess"
@error="handleError"
@progress="handleProgress"
@remove="handleRemove"
@exceed="handleExceed"
@exceed-size="handleExceedSize"
>
<template #default>
<div class="upload-drag-area">
<p class="upload-drag-icon">📁</p>
<p class="upload-drag-text">将文件拖到此处,或点击上传</p>
<p class="upload-drag-hint">
支持 PDF、Word、Excel、ZIP 格式,单个文件不超过 10MB
</p>
</div>
</template>
<template #tip>
<div class="upload-tip">
<p>支持扩展名:.pdf .doc .docx .xls .xlsx .zip</p>
<p>单个文件大小不超过 10MB,最多上传 5 个文件</p>
</div>
</template>
</FileUpload>
<div class="upload-actions">
<a-space>
<a-button type="primary" @click="handleSubmit">开始上传</a-button>
<a-button @click="handleClear">清空列表</a-button>
</a-space>
</div>
</div>
</template>
<style scoped>
.upload-drag-area {
padding: 60px 40px;
text-align: center;
background: #fafafa;
border: 2px dashed #d9d9d9;
border-radius: 8px;
transition: all 0.3s;
}
.upload-drag-area:hover {
border-color: #40a9ff;
background: #f0f8ff;
}
.upload-drag-icon {
font-size: 64px;
margin-bottom: 16px;
}
.upload-drag-text {
font-size: 16px;
color: #333;
margin-bottom: 8px;
}
.upload-drag-hint {
font-size: 14px;
color: #999;
}
.upload-tip {
margin-top: 8px;
color: #999;
font-size: 12px;
}
.upload-tip p {
margin: 4px 0;
}
.upload-actions {
margin-top: 16px;
}
</style>自定义上传
vue
<script setup lang="ts">
import { ref } from 'vue'
import { FileUpload } from '@vben/common-ui'
import axios from 'axios'
const fileList = ref<string[]>([])
const customUpload = async (file: File) => {
const formData = new FormData()
formData.append('file', file)
const { data } = await axios.post('/api/upload', formData, {
headers: { 'Content-Type': 'multipart/form-data' },
onUploadProgress: (progressEvent) => {
const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total!)
console.log(`上传进度:${percent}%`)
}
})
return data.url
}
</script>
<template>
<FileUpload
v-model="fileList"
:custom-request="customUpload"
/>
</template>文件预览
vue
<script setup lang="ts">
import { ref } from 'vue'
import { FileUpload } from '@vben/common-ui'
const fileList = ref<string[]>([])
const handlePreview = (file: UploadFile) => {
// 根据文件类型进行预览
const fileType = file.name.split('.').pop()?.toLowerCase()
if (['jpg', 'jpeg', 'png', 'gif'].includes(fileType!)) {
// 图片预览
window.open(file.url)
} else if (fileType === 'pdf') {
// PDF 预览
window.open(file.url)
} else {
// 下载文件
const link = document.createElement('a')
link.href = file.url!
link.download = file.name
link.click()
}
}
</script>
<template>
<FileUpload
v-model="fileList"
@preview="handlePreview"
/>
</template>注意事项
注意
- 上传的文件会自动转换为 URL 或返回服务器地址
- 多文件上传时,返回的是数组格式
- 建议设置合理的文件大小限制,避免上传过大的文件
- 拖拽上传需要浏览器支持 HTML5 Drag and Drop API
提示
- 可以通过
accept属性限制上传的文件类型 - 使用
maxSize属性限制文件大小 - 设置
autoUpload={false}可以手动控制上传时机 - 使用
customRequest可以完全自定义上传逻辑