#Upload 文件上传
选择或拖拽文件,查看上传进度。
#选择与校验
图片、PDF 或文本 · 最多 5 个文件,每个不超过 5 MB
basic.tsx
import { Space, Upload } from '@ifhover/leaf-ui';
export function UploadBasic() {
return (
<Space direction="vertical" align="stretch">
<Upload
multiple
accept="image/*,.pdf,.txt"
maxCount={5}
maxSize={5 * 1024 * 1024}
hint="图片、PDF 或文本 · 最多 5 个文件,每个不超过 5 MB"
/>
</Space>
);
}
#拖拽、进度与取消
此示例在本地模拟上传进度,使用 action 或 customRequest 接入实际上传服务。
advanced.tsx
import type { UploadRequest } from '@ifhover/leaf-ui';
import { Space, Text, Upload } from '@ifhover/leaf-ui';
const demoRequest = ({ signal, onProgress }: UploadRequest) =>
new Promise<void>((resolve, reject) => {
let percent = 0;
const cleanup = () => {
clearInterval(timer);
signal.removeEventListener('abort', abort);
};
const abort = () => {
cleanup();
reject(new DOMException('Aborted', 'AbortError'));
};
const timer = setInterval(() => {
percent += 12;
onProgress(percent);
if (percent >= 100) {
cleanup();
resolve();
}
}, 180);
signal.addEventListener('abort', abort, { once: true });
if (signal.aborted) abort();
});
export function UploadDrag() {
return (
<Space direction="vertical" align="stretch">
<Text tone="muted">
此示例在本地模拟上传进度,使用 action 或 customRequest 接入实际上传服务。
</Text>
<Upload
drag
multiple
accept="image/*"
maxCount={4}
customRequest={demoRequest}
hint="仅限图片 · 支持取消与重试"
/>
</Space>
);
}
#使用说明
未配置 action 或 customRequest 时只选择文件,保持待上传状态,可由业务统一提交。action 使用 XMLHttpRequest 报告进度:POST 发送 FormData,PUT 发送文件本身。JSON 响应可提供 url 和 name;customRequest 可返回相同字段。选择和拖拽共用校验,上传支持取消、移除与重试;自定义请求须响应 signal。移除或卸载会取消请求并释放本地预览 URL。服务端仍需进行文件校验。
#类型
import type { UploadProps, UploadFile, UploadChangeInfo, UploadRejection, UploadRequest, UploadResult, FileItem } from '@ifhover/leaf-ui';#手动上传与图片卡片
capabilities.tsx
import { Button, Space, Upload, type UploadHandle } from '@ifhover/leaf-ui';
import { useRef } from 'react';
export function Capabilities() {
const upload = useRef<UploadHandle>(null);
return (
<Space direction="vertical" align="stretch">
<Upload
ref={upload}
autoUpload={false}
concurrency={2}
multiple
accept="image/*"
listType="picture-card"
paste
customRequest={async (request) => {
await new Promise<void>((resolve, reject) => {
const timer = setTimeout(resolve, 700);
request.signal.addEventListener(
'abort',
() => {
clearTimeout(timer);
reject(request.signal.reason);
},
{ once: true },
);
});
return {};
}}
/>
<Space>
<Button onClick={() => upload.current?.upload()}>
{'开始上传'}
</Button>
<Button variant="outline" onClick={() => upload.current?.abort()}>
{'取消上传'}
</Button>
</Space>
</Space>
);
}
#UploadProps API
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
fileList | readonly UploadFile[] | [] | 受控 / 初始文件列表 |
defaultFileList | readonly UploadFile[] | [] | 受控 / 初始文件列表 |
onChange | (files: UploadFile[], info: UploadChangeInfo) => void | — | 列表及上传状态变化 |
accept | string | — | 允许的 MIME 或后缀,如 image/*,.pdf |
multiple | boolean | false | 多文件选择 / 禁用 / 拖拽区域 |
disabled | boolean | false | 禁用交互。 |
drag | boolean | false | 多文件选择 / 禁用 / 拖拽区域 |
maxCount | number | — | 允许的文件总数 |
maxSize | number | — | 单个文件最大字节数 |
beforeUpload | (file: File) => boolean | File | Promise<boolean | File> | — | 上传前校验,false 拒绝,File 可转换文件 |
onReject | (rejections: readonly UploadRejection[]) => void | — | 格式、大小、数量或校验拒绝 |
action | string | ((file: File) => string | Promise<string>) | — | 上传地址,未配置时只选择文件 |
method | 'POST' | 'PUT' | 'POST' | POST 使用 FormData,PUT 上传文件本身 |
headers | Readonly<Record<string, string>> | — | 请求头 |
data | Readonly<Record<string, string | Blob>> | — | POST 的额外表单数据 |
withCredentials | boolean | false | 跨域发送凭证 |
fieldName | string | 'file' | POST 中的文件字段名 |
customRequest | (request: UploadRequest) => Promise<UploadResult | void> | — | 自定义异步上传,配合 signal 取消 |
onRemove | (file: UploadFile) => boolean | void | Promise<boolean> | Promise<void> | — | 移除前回调,返回 false 保留文件 |
showFileList | boolean | true | 展示文件列表 |
hint | ReactNode | — | 提示 / 选择按钮或拖拽区域标题 |
children | ReactNode | — | 提示 / 选择按钮或拖拽区域标题 |
name | string | — | 原生 FormData 中的字段名。 |
form | string | — | 关联的原生表单 ID。 |
required | boolean | — | 要求整体值非空,复合控件只校验一次。 |
autoUpload | boolean | true | 文件校验通过后自动开始;false 时用 ref.upload()。 |
concurrency | number | 3 | 同时进行的上传请求数。 |
directory | boolean | — | 选择目录及其文件;依赖浏览器的目录选择能力。 |
paste | boolean | — | 接收剪贴板中的文件。 |
listType | 'text' | 'picture' | 'picture-card' | 'text' | 文件列表的展示形式。 |
#UploadFile API
继承 FileItem,并增加以下字段。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
uid | string | 必填 | 必需。唯一标识 |
url | string | — | 设置 url。 |
name | string | — | 原生 FormData 中的字段名。 |
size | number | — | 展示尺寸。 |
type | string | — | 设置 type。 |
status | 'ready' | 'uploading' | 'done' | 'error' | 'cancelled' | — | 设置 status。 |
percent | number | — | 完成百分比。 |
error | string | — | 设置 error。 |
originFile | globalThis.File | — | 设置 originFile。 |
response | unknown | — | 服务端返回的数据 |
#UploadChangeInfo API
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
file | UploadFile | — | 本次变化的文件 |
reason | 'add' | 'progress' | 'success' | 'error' | 'remove' | 'cancel' | 必填 | 必需。变化原因 |
#UploadRejection API
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
file | File | 必填 | 必需。被拒绝的文件 |
reason | 'type' | 'size' | 'count' | 'validation' | 必填 | 必需。拒绝原因 |
message | string | 必填 | 必需。用户可读的说明 |
#UploadRequest API
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
file | File | 必填 | 必需。待上传文件 |
signal | AbortSignal | 必填 | 必需。取消信号,移除或卸载也会取消 |
onProgress | (percent: number) => void | 必填 | 必需。报告上传进度 |
#UploadResult API
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
url | string | — | 上传后的地址 / 名称 |
name | string | — | 上传后的地址 / 名称 |
response | unknown | — | 保留业务响应 |
#FileItem API
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
uid | string | — | 稳定标识,建议提供 |
url | string | — | 文件地址 |
name | string | — | 文件名称,默认取 URL 的文件名 |
size | number | — | 字节数,可不提供;未提供时不显示大小 |
type | string | — | MIME 类型,未提供时根据扩展名识别 |
status | 'ready' | 'uploading' | 'done' | 'error' | 'cancelled' | — | 上传状态,可不提供 |
percent | number | — | 上传进度 0–100 |
error | string | — | 失败说明 |
originFile | File | — | 浏览器选择的原始文件 |
#UploadHandle
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
upload | (uid?: string) => void | — | 必需。开始指定文件或所有待处理文件的上传。 |
abort | (uid?: string) => void | — | 必需。取消指定文件或所有上传。 |
focus | () => void | — | 必需。聚焦控件。 |