Upload 上传
文件选择上传和拖拽上传组件。
基础用法
最简单的上传组件用法。
vue
<template>
<ex-upload
action="/api/upload"
:on-success="handleSuccess"
:on-error="handleError"
>
<ex-button type="primary">
<ex-icon name="upload" />
选择文件
</ex-button>
</ex-upload>
</template>
<script setup>
const handleSuccess = (response, file, fileList) => {
console.log('上传成功:', response)
}
const handleError = (error, file, fileList) => {
console.error('上传失败:', error)
}
</script>拖拽上传
支持拖拽文件到指定区域进行上传。
vue
<template>
<ex-upload
action="/api/upload"
drag
:on-success="handleSuccess"
>
<div class="upload-dragger">
<ex-icon name="upload" style="font-size: 48px; color: #999;" />
<div>将文件拖到此处,或<em>点击上传</em></div>
</div>
</ex-upload>
</template>
<script setup>
const handleSuccess = (response, file, fileList) => {
console.log('上传成功:', response)
}
</script>文件列表
显示已选择的文件列表,支持不同的展示样式。
vue
<template>
<div>
<h4>文本列表</h4>
<ex-upload
action="/api/upload"
list-type="text"
:file-list="fileList1"
@update:file-list="fileList1 = $event"
>
<ex-button>选择文件</ex-button>
</ex-upload>
<h4>图片列表</h4>
<ex-upload
action="/api/upload"
list-type="picture"
:file-list="fileList2"
@update:file-list="fileList2 = $event"
>
<ex-button>选择图片</ex-button>
</ex-upload>
<h4>卡片列表</h4>
<ex-upload
action="/api/upload"
list-type="picture-card"
:file-list="fileList3"
@update:file-list="fileList3 = $event"
>
<div class="upload-card">
<ex-icon name="plus" />
<div>上传</div>
</div>
</ex-upload>
</div>
</template>
<script setup>
import { ref } from 'vue'
const fileList1 = ref([])
const fileList2 = ref([])
const fileList3 = ref([])
</script>文件限制
限制上传文件的类型、大小和数量。
vue
<template>
<div>
<h4>限制文件类型</h4>
<ex-upload
action="/api/upload"
accept="image/*"
:on-exceed="handleExceed"
>
<ex-button>只能上传图片</ex-button>
</ex-upload>
<h4>限制文件大小</h4>
<ex-upload
action="/api/upload"
:max-size="1024 * 1024"
:before-upload="beforeUpload"
>
<ex-button>文件大小不超过1MB</ex-button>
</ex-upload>
<h4>限制文件数量</h4>
<ex-upload
action="/api/upload"
:max-count="3"
multiple
:on-exceed="handleExceed"
>
<ex-button>最多上传3个文件</ex-button>
</ex-upload>
</div>
</template>
<script setup>
const handleExceed = (files, fileList) => {
console.warn('文件数量超出限制')
}
const beforeUpload = (file) => {
const isLt1M = file.size / 1024 / 1024 < 1
if (!isLt1M) {
console.error('文件大小不能超过 1MB!')
return false
}
return true
}
</script>手动上传
关闭自动上传,手动控制上传时机。
vue
<template>
<div>
<ex-upload
ref="uploadRef"
action="/api/upload"
:auto-upload="false"
multiple
:on-change="handleChange"
>
<ex-button>选择文件</ex-button>
</ex-upload>
<div style="margin-top: 16px;">
<ex-button type="primary" @click="submitUpload">上传到服务器</ex-button>
<ex-button @click="clearFiles">清空文件</ex-button>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const uploadRef = ref()
const handleChange = (info) => {
console.log('文件列表变化:', info.fileList)
}
const submitUpload = () => {
uploadRef.value.submit()
}
const clearFiles = () => {
uploadRef.value.clearFiles()
}
</script>自定义上传
使用自定义的上传实现。
vue
<template>
<ex-upload
:custom-request="customUpload"
:show-file-list="false"
>
<ex-button :loading="uploading">
{{ uploading ? '上传中...' : '自定义上传' }}
</ex-button>
</ex-upload>
</template>
<script setup>
import { ref } from 'vue'
const uploading = ref(false)
const customUpload = async (option) => {
uploading.value = true
try {
const formData = new FormData()
formData.append('file', option.file)
const response = await fetch('/api/custom-upload', {
method: 'POST',
body: formData,
onUploadProgress: (progressEvent) => {
const percent = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
)
option.onProgress({ percent })
}
})
const result = await response.json()
option.onSuccess(result)
} catch (error) {
option.onError(error)
} finally {
uploading.value = false
}
}
</script>图片预览
支持图片文件的预览功能。
vue
<template>
<ex-upload
action="/api/upload"
list-type="picture-card"
:on-preview="handlePreview"
:file-list="fileList"
@update:file-list="fileList = $event"
>
<div class="upload-card">
<ex-icon name="plus" />
<div>上传</div>
</div>
</ex-upload>
</template>
<script setup>
import { ref } from 'vue'
const fileList = ref([
{
uid: '1',
name: 'image1.png',
status: 'success',
url: 'https://example.com/image1.png'
},
{
uid: '2',
name: 'image2.jpg',
status: 'success',
url: 'https://example.com/image2.jpg'
}
])
const handlePreview = (file) => {
console.log('预览文件:', file)
// 可以在这里实现自定义预览逻辑
}
</script>上传进度
显示文件上传进度。
vue
<template>
<ex-upload
action="/api/upload"
:on-progress="handleProgress"
:on-success="handleSuccess"
:on-error="handleError"
>
<ex-button>上传文件</ex-button>
</ex-upload>
</template>
<script setup>
const handleProgress = (event, file, fileList) => {
console.log(`上传进度: ${event.percent}%`)
}
const handleSuccess = (response, file, fileList) => {
console.log('上传成功:', file.name)
}
const handleError = (error, file, fileList) => {
console.error('上传失败:', file.name, error)
}
</script>API
Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| action | 上传的地址 | string | '' |
| method | 上传请求的方法 | string | 'post' |
| name | 上传的文件字段名 | string | 'file' |
| data | 上传时附带的额外参数 | object | {} |
| headers | 设置上传的请求头部 | object | {} |
| withCredentials | 支持发送 cookie 凭证信息 | boolean | false |
| multiple | 是否支持多选文件 | boolean | false |
| accept | 接受上传的文件类型 | string | '' |
| maxSize | 限制文件大小(字节) | number | undefined |
| maxCount | 限制文件数量 | number | undefined |
| drag | 是否启用拖拽上传 | boolean | false |
| disabled | 是否禁用 | boolean | false |
| autoUpload | 是否自动上传 | boolean | true |
| showFileList | 是否显示文件列表 | boolean | true |
| listType | 文件列表的类型 | 'text' | 'picture' | 'picture-card' | 'text' |
| fileList | 文件列表 | UploadFile[] | [] |
| size | 组件大小 | 'small' | 'medium' | 'large' | 'medium' |
| buttonType | 按钮类型 | 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'primary' |
| buttonText | 按钮文本 | string | undefined |
| tip | 提示文本 | string | undefined |
| showTip | 是否显示提示 | boolean | true |
Events
| 事件名 | 说明 | 参数 |
|---|---|---|
| update:fileList | 文件列表更新时触发 | (fileList: UploadFile[]) |
| change | 文件状态改变时触发 | (param: UploadChangeParam) |
| beforeUpload | 文件上传前的钩子 | (file: File, fileList: UploadFile[]) |
| progress | 文件上传进度 | (event: UploadProgressEvent, file: UploadFile, fileList: UploadFile[]) |
| success | 文件上传成功时触发 | (response: any, file: UploadFile, fileList: UploadFile[]) |
| error | 文件上传失败时触发 | (error: Error, file: UploadFile, fileList: UploadFile[]) |
| preview | 点击文件预览时触发 | (file: UploadFile) |
| remove | 文件移除时触发 | (file: UploadFile, fileList: UploadFile[]) |
| download | 点击下载文件时触发 | (file: UploadFile) |
| exceed | 文件超出数量限制时触发 | (files: File[], fileList: UploadFile[]) |
Methods
| 方法名 | 说明 | 参数 |
|---|---|---|
| submit | 手动上传文件列表 | () |
| clearFiles | 清空文件列表 | () |
| abort | 取消上传请求 | (file?: UploadFile) |
Slots
| 插槽名 | 说明 | 参数 |
|---|---|---|
| default | 默认插槽,上传按钮内容 | { click: Function } |
| trigger | 触发上传的元素 | { click: Function } |
| tip | 提示信息 | {} |
Types
typescript
interface UploadFile {
uid: string
name: string
size?: number
type?: string
status: 'ready' | 'uploading' | 'success' | 'error'
percent?: number
url?: string
thumbUrl?: string
response?: any
error?: any
originFileObj?: File
}
interface UploadProgressEvent {
percent: number
loaded: number
total: number
}
interface UploadChangeParam {
file: UploadFile
fileList: UploadFile[]
}
interface UploadRequestOption {
action?: string
filename: string
file: File
data?: Record<string, any>
headers?: Record<string, string>
withCredentials?: boolean
onProgress?: (event: UploadProgressEvent) => void
onSuccess?: (response: any) => void
onError?: (error: Error) => void
}样式变量
组件提供了以下CSS变量用于自定义样式:
css
:root {
--ex-upload-drag-border-color: var(--ex-border-color);
--ex-upload-drag-bg-color: var(--ex-bg-color-page);
--ex-upload-drag-hover-border-color: var(--ex-color-primary);
--ex-upload-drag-hover-bg-color: var(--ex-color-primary-light-9);
--ex-upload-list-item-hover-bg: var(--ex-bg-color-page);
--ex-upload-progress-bg: var(--ex-color-primary);
}