Skip to content

Upload 上传

完整的文件上传系统,采用新粗野主义设计,支持拖拽上传、文件列表管理、进度追踪和错误处理。

预览

Preview

基础 text 类型

点击或拖拽文件到此区域上传

document.pdf

1.47 MB

avatar.png

312.5 KB

picture 缩略图列表类型

点击或拖拽文件到此区域上传

sunset.jpg

sunset.jpg

2.34 MB

picture-card 照片墙类型(最大限制 3 张)

点击或拖拽文件到此区域上传

landscape.jpg

landscape.jpg

安装

pnpm dlx brutx-vue@latest add upload

用法

vue
<script setup>
import { ref } from 'vue'
import { Upload, UploadTrigger, UploadFileList, type UploadFile } from 'brutx-ui-vue'

const fileList = ref<UploadFile[]>([])

async function handleUpload(options) {
    // 自定义上传实现
    const formData = new FormData()
    formData.append('file', options.file)

    const response = await fetch('/api/upload', {
        method: 'POST',
        body: formData,
    })

    options.onSuccess(response)
}
</script>

<template>
    <Upload
        v-model:file-list="fileList"
        :http-request="handleUpload"
        accept="image/*"
        :max-size="5 * 1024 * 1024"
    >
        <template #trigger="{ selectFiles, drag }">
            <UploadTrigger :drag="drag" @select="selectFiles" />
        </template>
        <template #file-list="{ files, remove, retry }">
            <UploadFileList :files="files" @remove="remove" @retry="retry" />
        </template>
    </Upload>
</template>

图片卡片类型

vue
<script setup>
import { ref } from 'vue'
import { Upload, UploadTrigger, UploadFileList, type UploadFile } from 'brutx-ui-vue'

const fileList = ref<UploadFile[]>([])
</script>

<template>
    <Upload
        v-model:file-list="fileList"
        list-type="picture-card"
        :limit="5"
        multiple
    >
        <template #trigger="{ selectFiles }">
            <UploadTrigger @select="selectFiles" />
        </template>
        <template #file-list="{ files, remove }">
            <UploadFileList :files="files" list-type="picture-card" @remove="remove" />
        </template>
    </Upload>
</template>

使用钩子函数

vue
<script setup>
import { ref } from 'vue'
import { Upload, UploadTrigger, UploadFileList, type UploadFile } from 'brutx-ui-vue'

const fileList = ref<UploadFile[]>([])

function beforeUpload(file) {
    const isImage = file.type.startsWith('image/')
    if (!isImage) {
        console.error('只能上传图片文件!')
        return false
    }
    return true
}

async function beforeRemove(file) {
    return confirm(`确定删除 ${file.name} 吗?`)
}
</script>

<template>
    <Upload
        v-model:file-list="fileList"
        :before-upload="beforeUpload"
        :before-remove="beforeRemove"
    >
        <template #trigger="{ selectFiles }">
            <UploadTrigger @select="selectFiles" />
        </template>
        <template #file-list="{ files, remove }">
            <UploadFileList :files="files" @remove="remove" />
        </template>
    </Upload>
</template>

子组件

组件说明
Upload根组件,管理文件列表和上传逻辑
UploadTrigger触发区域,支持拖拽/点击选择文件
UploadFileList文件列表容器
UploadFileItem单个文件项,支持预览、进度和删除

Props

Upload

属性类型默认值说明
fileListUploadFile[][]文件列表,支持 v-model:fileList
limitnumber最大文件数量
multiplebooleantrue是否支持多选
acceptstring接受的文件类型(如 image/*.pdf,.doc
maxSizenumber最大文件大小(字节)
maxRetriesnumber3最大重试次数
beforeUpload(file: File) => boolean | Promise<boolean>上传前钩子
beforeRemove(file: UploadFile) => boolean | Promise<boolean>删除前钩子
httpRequest(options: UploadRequestOptions) => Promise<void>自定义上传实现
listType'text' | 'picture' | 'picture-card''text'列表显示类型
autoUploadbooleantrue选择后是否自动上传
dragbooleantrue是否支持拖拽
onError(error: UploadError, file: UploadFile) => void错误回调
classstring自定义 CSS 类

UploadTrigger

属性类型默认值说明
dragbooleantrue是否支持拖拽
disabledbooleanfalse是否禁用
acceptstring接受的文件类型
multiplebooleantrue是否支持多选
classstring自定义 CSS 类

UploadFileList

属性类型默认值说明
filesUploadFile[]—(必填)文件列表
listType'text' | 'picture' | 'picture-card''text'列表显示类型
classstring自定义 CSS 类

类型定义

UploadFile

typescript
interface UploadFile {
    id: string
    name: string
    size: number
    type: string
    status: 'ready' | 'uploading' | 'success' | 'error'
    progress: number
    url?: string
    raw?: File
    error?: UploadError
}

UploadError

typescript
interface UploadError {
    message: string
    code?: string
    status?: number
}

UploadRequestOptions

typescript
interface UploadRequestOptions {
    file: File
    onProgress: (percent: number) => void
    onSuccess: (response: unknown) => void
    onError: (error: UploadError) => void
}

事件

Upload

事件参数说明
update:fileListUploadFile[]文件列表变化时触发
file-changeUploadFile添加文件时触发
file-removeUploadFile删除文件时触发
file-successUploadFile文件上传成功时触发
file-error[UploadFile, UploadError]文件上传失败时触发

UploadTrigger

事件参数说明
selectFileList选择文件时触发

暴露的方法

Upload

方法说明
handleFileSelect(files)编程式添加文件
handleFileRemove(file)删除文件
retryUpload(file)重试上传失败的文件

插槽

Upload

插槽作用域说明
trigger{ selectFiles, limit, multiple, accept, drag }触发区域插槽
file-list{ files, listType, remove, retry }文件列表插槽

UploadTrigger

插槽作用域说明
default{ isDragging }自定义触发内容
text主要文本
hint提示文本

可访问性

  • 键盘操作:触发区域可通过 Enter / Space 键激活
  • ARIA 属性:隐藏的文件输入框有正确的标签
  • 屏幕阅读器:文件状态和进度会被播报

蛮力铸就。