Appearance
File Upload 文件上传
选择或拖入本地文件,支持类型、大小、数量校验及后端文件回显。组件不发起 HTTP 请求。
命令行安装
bash
npx @loongship-kit/ui add file-upload基础用法
使用 v-model:file-list 获取文件列表。默认是单文件模式,再次选择会替换原文件。
已选择:暂无文件
查看代码
vue
<script setup lang="ts">
import { ref } from 'vue'
import { FileUpload } from '@/components/loongship/file-upload'
import type { FileUploadItem } from '@/components/loongship/file-upload'
const files = ref<FileUploadItem[]>([])
</script>
<template>
<div>
<FileUpload v-model:file-list="files" />
<span>已选择:{{ files[0]?.name || '暂无文件' }}</span>
</div>
</template>拖拽上传
设置 drag 后切换为拖拽投放区,同时仍可点击打开文件选择器。
查看代码
vue
<script setup lang="ts">
import { ref } from 'vue'
import { FileUpload } from '@/components/loongship/file-upload'
import type { FileUploadItem } from '@/components/loongship/file-upload'
const files = ref<FileUploadItem[]>([])
</script>
<template>
<FileUpload v-model:file-list="files" drag />
</template>多文件与文件限制
multiple 模式会把新文件追加到现有列表,并以文件名、大小和最后修改时间去重。下面的示例最多接收 3 个 PDF 或图片文件,且每个文件不超过 5 MB。
已接收 0 个,最近拒绝 0 个。
查看代码
vue
<script setup lang="ts">
import { ref } from 'vue'
import { FileUpload } from '@/components/loongship/file-upload'
import type { FileUploadItem, FileUploadRejection } from '@/components/loongship/file-upload'
const attachments = ref<FileUploadItem[]>([])
const lastRejections = ref<FileUploadRejection[]>([])
</script>
<template>
<div>
<FileUpload
v-model:file-list="attachments"
multiple
accept=".pdf,image/*"
:max-size="5 * 1024 * 1024"
:max-files="3"
@reject="lastRejections = $event"
/>
<span>已接收 {{ attachments.length }} 个,最近拒绝 {{ lastRejections.length }} 个。</span>
</div>
</template>文件接收规则
accept 支持逗号分隔的扩展名、精确 MIME 和 MIME 通配符,例如 .pdf,application/json,image/*。浏览器选择器会使用同一规则作为提示,组件仍会在接收文件时再次校验。
自定义内容
trigger、file 和 error 插槽分别自定义触发器、文件项和错误内容。
vue
<template>
<FileUpload v-model:file-list="files" multiple>
<template #trigger="{ disabled }">
<span :aria-disabled="disabled">添加附件</span>
</template>
<template #file="{ file, remove }">
<span>{{ file.name }}</span>
<button type="button" @click="remove">删除</button>
</template>
<template #error="{ rejections }">
<span>{{ rejections.map(item => item.message).join(';') }}</span>
</template>
</FileUpload>
<FileUpload v-model:file-list="files" drag>
<template #trigger="{ dragging }">
<span>{{ dragging ? '松开以添加文件' : '把附件拖到这里' }}</span>
</template>
</FileUpload>
</template>上传文件
监听 select,或从 fileList 中筛选带有 raw 的本地文件后自行上传:
ts
const formData = new FormData()
for (const item of files.value) {
if (item.raw) formData.append('files', item.raw)
}不要依赖原生表单上传
组件在处理每次原生选择后会清空内部 input,使再次选择同一文件仍能触发事件。请使用文件项的 raw 自行上传,不要依赖原生表单的 multipart/form-data 提交。
后端回显
后端文件提供文件名和 URL 即可;有稳定标识时可传入 uid:
ts
const files = ref<FileUploadItem[]>([
{
name: '航次报告.pdf',
size: 102400,
type: 'application/pdf',
url: '/api/files/1001'
}
])后端项通常具有 url 而没有 raw;本地新增项具有 raw,并由组件自动生成 uid。删除、排序和展示都通过同一个 fileList 完成。
API
属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
v-model:file-list | FileUploadItem[] | - | 受控文件项列表 |
defaultFileList | FileUploadItem[] | - | 非受控模式初始文件项 |
multiple | boolean | false | 是否允许多个文件 |
drag | boolean | false | 是否启用拖拽投放区 |
accept | string | - | 扩展名或 MIME 接收规则 |
maxSize | number | - | 单文件最大字节数 |
maxFiles | number | - | 多文件模式最大数量 |
disabled | boolean | false | 禁止选择、拖入和删除 |
prompt | string | '拖拽文件到此处,或' | 默认投放区提示 |
browseLabel | string | '选择文件' | 选择文本及原生 input 可访问名 |
removeLabel | string | '移除文件' | 删除按钮可访问名 |
class | ClassValue | - | 根元素自定义类名 |
事件
| 事件 | 参数 | 说明 |
|---|---|---|
update:fileList | files: FileUploadItem[] | 文件项列表改变 |
select | files: FileUploadItem[] | 本次成功接收的新增文件项 |
reject | rejections: FileUploadRejection[] | 本次拒绝的全部文件及原因 |
remove | file: File, index: number | 文件被移除 |
拒绝原因
拒绝码为 type、size、count 或 duplicate。一次操作可以同时接收有效文件并拒绝无效文件。
FileUploadItem
| 字段 | 类型 | 说明 |
|---|---|---|
uid | string | 可选列表标识;本地项由组件自动生成 |
name | string | 文件名 |
size | number | 可选文件大小,单位字节 |
type | string | 可选 MIME 类型 |
url | string | 可选预览或下载地址,通常用于后端回显 |
raw | File | 可选原生文件,仅本地新增项具有 |
插槽
| 插槽 | 参数 | 说明 |
|---|---|---|
trigger | dragging, disabled, files | 两种模式共用的文件选择触发器 |
file | file, index, remove() | 单个文件项 |
error | rejections | 最近拒绝提示内容 |