Appearance
FUpload 附件上传
FUpload / FinUpload 是可嵌入页面、FForm 或 FDialog 的内容组件,不内置弹框,也不绑定任何后端接口。基于 Element Plus ElUpload 选择文件,使用独立队列和宿主 upload 回调执行上传,不调用 Element Plus 默认 HTTP 上传。
基础用法
loading
组件根据正数 limit / maxSize 自动生成中英文限制提示,大小按 1024 换算为 KiB / MiB 等单位。拖拽模式提示位于拖拽区域内主文案下方;普通模式位于上传按钮旁,窄屏时可换行。提示不出现在附件列表或列表项中,无数量和大小约束时不生成空白提示;accept 仍用于文件选择和类型校验,不自动展开为提示文案。
tip 插槽可替换默认限制提示,始终位于上传触发区内部;trigger 插槽替换选择内容但不移除提示。只读模式隐藏整个上传区域及提示。基础示例无需重复手写限制文案;其中文件名含 fail 的文件首次模拟上传失败,可通过重试验证恢复行为。
成功附件与临时队列
v-model: UploadAttachment[]只包含成功附件。传入已有附件即可回显;正在上传、失败、取消的文件不会写入业务值。- 每个成功附件必须有唯一的
id(string / number)和name;url、size、type、metadata可选。宿主把接口响应映射成此结构,组件不会推断后端字段。 queue-change提供临时UploadQueueItem[]快照,包含uid、file、name、status、percentage和可选error。状态为uploading/failed/canceled。成功后从队列移除并写入v-model。limit计算成功附件与全部临时队列的总数,失败/取消项也占位。移除后释放名额。- 成功附件顺序为完成上传的顺序。并发完成不会因父组件尚未回传值而丢失附件。父组件主动替换
v-model时更新回显,但不清空临时队列;切换业务记录建议用:key="recordId"重新挂载。 - 提交前检查队列:上传期间不能仅凭成功附件数组判定全部完成。失败/取消文件是否阻止提交由宿主决定。
上传回调
ts
import type { UploadAttachment, UploadHandler } from '@axewo/fin-ui'
const attachments = ref<UploadAttachment[]>([])
const upload: UploadHandler = async (file, { signal, onProgress }) => {
// 宿主封装自己的请求;进度为 0–100 百分比,signal 用于取消。
const result = await attachmentService.upload(file, { signal, onProgress })
return {
id: result.fileId,
name: file.name,
url: result.downloadUrl,
size: file.size,
type: file.type,
}
}vue
<FUpload
v-model="attachments"
:upload="upload"
:limit="10"
accept=".pdf,image/*"
:max-size="10485760"
/>取消、移除临时项、切换只读/禁用或卸载时触发 AbortSignal。宿主应真正终止请求;即使忽略 signal,组件也不会接受过期成功结果或进度。重试仍使用同一个本地 File,但创建新的 AbortSignal。回调拒绝、返回缺少 id/name 的结果或重复 id 时显示失败并允许重试。
FForm / FDialog
已内置注册 component: 'FUpload':
ts
const schemas: FormSchema[] = [
{
field: 'attachments',
label: '附件',
component: 'FUpload',
defaultValue: [],
componentProps: { upload, limit: 5, accept: '.pdf', maxSize: 5 * 1024 * 1024 },
},
]成功或移除附件会触发表单 change 校验。继承 ElForm 的禁用状态。FForm 的 view 场景是通用字段展示器;若需可预览附件列表,应通过 schema 自定义 render,在 mode === 'view' 时渲染 FUpload readonly。在 FDialog 中直接放入组件即可,是否阻止关闭/提交由宿主决定。
预览与下载
成功附件提供 url 时,默认生成安全的新窗口链接;允许 http: / https: / blob:,拒绝 javascript: 等危险协议。没有 URL 或回调的操作按钮禁用。preview / download 回调可替代默认行为,处理鉴权下载、签名地址、图片查看器等。只读或禁用不影响预览/下载。
附件列表按成品风格展示:文件类型图标(图片/识别 PDF/普通文件)+ 名称省略 + 大小 + 右侧文字操作按钮;行悬停有背景反馈。上传中队列项单独一行显示名称、大小、百分比进度条与取消按钮;失败项显示失败原因并提供重试;已取消项提供重试。可通过 attachment 插槽完全自定义成功附件行。
浏览器的 download 属性对跨域链接可能无效,后端需设置 Content-Disposition 或由宿主自行下载 Blob。组件不创建或回收对象 URL;使用 Blob URL 时由宿主管理生命周期。移除仅更新本地业务值,不发送后端删除请求。
API
Props
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| modelValue | UploadAttachment[] | [] | 仅成功附件,可回显 |
| upload | UploadHandler | 必填 | (file, { signal, onProgress }) => Promise<UploadAttachment> |
| multiple | boolean | true | 文件选择器允许多选;false 不限制累计附件数量 |
| limit | number | 0 | 总数量上限,0 不限 |
| accept | string | '' | 逗号分隔扩展名/MIME/通配 MIME,例如 .pdf,image/* |
| maxSize | number | 0 | 单文件字节上限,0 不限 |
| readonly | boolean | false | 隐藏选择、重试、取消、移除,禁止方法变更 |
| disabled | boolean | false | 禁止选择和变更,终止在途请求 |
| preview | (attachment) => void | Promise<void> | — | 自定义预览 |
| download | (attachment) => void | Promise<void> | — | 自定义下载 |
FinUploadProps 通过 Partial<Omit<UploadProps, ManagedUploadProps>> 继承 Element Plus 原生类型,只额外声明业务属性。multiple、accept、disabled 直接复用原生类型;另外支持 drag(默认 false,提供默认拖拽区域)、directory(默认 false,选择目录内文件,浏览器需支持 webkitdirectory),均实际传给 ElUpload。trigger 插槽在普通和拖拽模式下均可替换默认内容。
排除边界:action、method、headers、data、name、withCredentials、httpRequest、autoUpload、fileList、showFileList;原生 beforeUpload、beforeRemove、onRemove、onChange、onPreview、onSuccess、onProgress、onError、onExceed;以及 limit、listType、crossorigin。其中 limit 按成功附件加临时队列的业务语义重新声明;listType 和仅影响原生缩略图的 crossorigin 不适用于自定义附件列表。事件请使用下述业务 Events,而非原生生命周期钩子。
按当前安装的 Element Plus 2.14.2 核对,UploadProps 不包含 tabindex,因此不提供该 prop;选择区域键盘行为沿用 ElUpload。组件不透传任意 attrs,排除项即使在运行时传入也不会传给 ElUpload。上传始终使用业务 upload 回调,原生 autoUpload 固定 false,不启用默认 HTTP 流。
Events
| 事件 | 参数 | 说明 |
|---|---|---|
| update:modelValue / change | UploadAttachment[] | 成功附件新增或移除 |
| queue-change | UploadQueueItem[] | 队列状态或进度改变 |
| success | attachment, file | 单文件上传成功 |
| error | error, item | 单文件失败 |
| reject | file, reason | 上传前限制,reason 为 limit/type/size;不进入队列 |
| remove | attachment | 成功附件移除;临时项移除见 queue-change |
| preview / download | attachment | 执行对应操作 |
| action-error | error, action, attachment | 自定义预览/下载执行失败 |
Slots
| 插槽 | 参数 | 说明 |
|---|---|---|
| trigger | — | 自定义文件选择按钮,放在 ElUpload 内 |
| tip | — | 上传区内部的帮助内容,替换默认限制提示;只读时隐藏 |
| attachment | { attachment } | 完全替换成功附件行内容(包括操作按钮) |
Exposed
FinUploadExposed 包含:addFiles(files: File[])、retry(uid)、cancel(uid)、removeQueued(uid)、remove(id)、getQueue()、isUploading()。使用 ref 调用;变更方法同样受 readonly/disabled/ElForm disabled 约束。getQueue() 返回浅快照,不会暴露可修改的内部队列项(File/error 本身不深拷贝)。
导出
主入口导出 FUpload、FinUpload,以及 UploadAttachment、UploadQueueItem、UploadQueueStatus、UploadContext、UploadHandler、UploadRejectReason、FinUploadProps、FinUploadEmits、FinUploadExposed。全量 app.use(FinUI) 注册两个名字;FinUIResolver() 支持两个名字与默认样式导入。
边界
客户端类型检查依赖扩展名或浏览器给出的 MIME,只用于交互限制,服务端必须再次校验大小、内容与权限。组件立即并发上传选中的文件,目录选择仅将文件逐个交给 upload,不保留目录树或自动创建远端目录;不提供分片、断点续传、并发上限、服务端删除或持久化失败队列。切换只读/禁用时的取消项需解除限制后主动重试。