Skip to content

Upload 上传 ​

点击或拖拽选择文件,展示文件列表与上传进度。支持真实上传通道(action XHR / custom-request 逃生舱)、上传前校验转换、失败重试与取消。

基础用法 ​

基础(选择文件)

多选与数量限制 ​

多选 + max

max 限制最多可选文件数,accept 过滤文件类型;超出 max 的文件被拒绝并派发 oas-exceed-limit。

自动上传 ​

自动上传(模拟进度)

auto-upload 时添加文件即自动上传;未设置 action / custom-request 时为模拟进度(内置定时器推进,仅作展示兜底,不发起网络请求),进度条复用 oas-progress。

拖拽上传 ​

拖拽上传

将文件直接拖入虚线区域,松开即添加(支持多选);拖入时区域高亮提示。disabled 时拖拽会显示禁止光标且不接收文件。

照片墙 ​

list-type 控制列表样式:list(默认,文本行)、picture(列表带小缩略图)、picture-card(卡片缩略图墙)。

picture-card 卡片墙 ​

照片墙(picture-card)

图片文件显示缩略图(URL.createObjectURL),非图片显示文件图标与文件名;点击缩略图打开预览浮层(Esc 或点击遮罩关闭),右上角 × 删除,hover 卡片出现预览/删除操作区。圆形头像卡可用 CSS 变量 --oas-upload-card-radius: 50% 达成。

触屏(pointer: coarse)下无 hover 可依赖:右上角删除×常显,失败/上传中卡片的操作遮罩常显(预览/重试/取消),删除×与操作钮触控热区扩展到 44px。

删除、预览与超限拦截 ​

照片墙 · 删除/预览/超限

选择/拖入第 4 张时被 max="3" 拦截,触发 oas-exceed-limit 弹出警告;点击缩略图触发 oas-preview。

picture 列表带缩略图 ​

列表带小缩略图(picture)

list / picture 模式下点击文件名同样打开预览浮层(文件名为可聚焦按钮)。

已达上限 ​

已达 max 上限(预置满 3 张)

预置满 max="3" 后继续选择会被 oas-exceed-limit 拦截。

禁用 ​

禁用

真实上传通道(action) ​

action 指定服务端地址后走内置 XHR 通道:name(表单文件字段名,默认 file)、data(附加表单字段 JSON)、headers(请求头 JSON)、method(默认 POST)、with-credentials 均透传;进度/成功/失败来自真实 XHR 事件。

action 通道(含失败重试演示)

文档站没有真实上传端点,/api/upload 返回 404,正好演示失败态:列表行转红色并出现重试按钮(⟳),点击重试重新发起请求;上传中可点 × 取消(派发 oas-cancel)。成功时派发 oas-success(detail: { file, response },response 为解析后的 JSON 或原文),失败派发 oas-error(detail: { file, response, status })。

自定义请求通道(custom-request) ​

分片上传、对象存储直传、WebSocket 等非标通道用 custom-request 函数 property 接管(组件不管请求策略):

custom-request 接管请求

js
el.customRequest = ({ file, name, action, onProgress, onSuccess, onError }) => {
  // 自行发起请求,回调节奏由宿主控制
  onProgress({ percent: 60 })
  onSuccess({ url: 'https://example.com/f.png' }) // 或 onError({ status: 500 })
  return { abort: () => {/* 取消 */} } // 可选:提供后上传中显示取消按钮
}

手动上传 ​

不加 auto-upload 即手动模式:选完文件后调用 submit()(startUpload() 的等价别名)统一提交。

手动上传(选完统一提交)

开始上传

上传前校验与转换(before-upload) ​

before-upload 函数 property:返回 false 拒绝文件;返回新 File 转换(改名/压缩等 transform 语义);支持异步 Promise。

before-upload 校验与转换

图片裁剪(crop) ​

crop 开启图片上传前裁剪。生效条件:list-type 为 picture / picture-card 且 accept 包含图片类型——此时选择/拖入/粘贴图片文件不再直接入列,而是弹出内建轻量裁剪对话框(自绘浮层,零依赖):

  • 移动:拖拽舞台空白处平移图像;拖拽裁剪框整体移动(聚焦后方向键微调,Shift 加速)
  • 缩放框体:拖拽右下角手柄;crop-aspect 设固定宽高比(如 1:1、16:9,非法/缺省为自由比例)
  • 缩放图像:舞台上滚轮,或工具栏放大/缩小按钮(100% = 铺满基准,上限 800%)
  • 确定:离屏 canvas 按源图自然分辨率导出裁剪区域,以结果文件入列代替原图,并派发 oas-crop(detail: { file, blob })
  • 取消 / Esc:不入列直接关闭;批量多选时逐张处理(取消跳过当前张、继续下一张),非图片文件不受影响直接入列

crop 裁剪后上传(picture-card + 1:1)

crop 与 before-upload 组合时先走 before-upload(含校验/转换),转换结果再进裁剪;确认入列仍受 max / max-size / replace 语义约束(裁剪结果可能比原图小,大小限制在入列时裁决)。

文件大小限制(max-size) ​

max-size 支持字节数或带单位写法(512KB / 2MB / 1GB);超限拒绝并派发 oas-exceed-limit(detail.type === 'size',含 maxSize 字节数)。

max-size(100KB)

超限替换(replace) ​

replace 开启后数量超限不再拒绝,而是移除最早的文件为新文件腾位(max=1 / 单选场景即「选新顶旧」,头像等高频场景免「先删再选」)。

replace(max=1,选择新文件自动替换)

目录与粘贴上传 ​

directory 开启目录上传(input 落 webkitdirectory,列表显示相对路径);paste 开启粘贴上传(组件上直接 Ctrl+V 剪贴板文件,截图场景高频,默认关闭)。

目录上传(directory)

粘贴上传(paste)

触发器、提示与列表项自定义 ​

  • slot="trigger":替换拖拽区内容(点击/拖拽语义保留在拖拽区容器上——zone 本身就是 role="button" 的可聚焦控件,内嵌内容不要再放按钮/链接等可交互元素(嵌套交互 axe 违规);展示性内容即可)
  • tip 属性或 template[slot="tip"]:拖拽区下方次要说明文案(属性优先)
  • template[slot="item"]:克隆进 list / picture 每行,[data-item-name] / [data-item-size] 自动绑定文件名与大小

trigger / tip 插槽

item 插槽(列表行自定义)

已上传回显与隐藏列表 ​

  • files / defaultFiles property 接受 { name, url, size? } 型回显记录(状态 done,预览走远程 url),编辑场景的初值语义
  • show-file-list="false" 隐藏内置列表,只留触发区(宿主自绘预览的前提)

已上传回显(defaultFiles)

头像上传(show-file-list=false + trigger 自绘 + before-upload 校验)

事件 ​

变化事件

监听 oas-change / oas-remove / oas-upload / oas-progress:

  • oas-upload:进度,detail: { file, percent, status }(status 仅 uploading / done;失败不在此事件,改走 oas-error)
  • oas-progress:上传进度回调(PRD P2),detail: { file, percent }——内部进度已驱动 UI,此事件补对外通道(真实 / 模拟 / custom-request 通道均派发,成功收尾派发 100)
  • oas-success / oas-error:上传成功/失败(真实通道),detail: { file, response, status? }
  • oas-retry / oas-cancel:重试发起 / 上传取消,detail: { file }
  • oas-exceed-limit:超限拒绝,detail: { files, max, total }(数量)或 { files, type: 'size', maxSize, total }(大小)
  • oas-remove:移除文件,detail: { file, index, replaced? }(replaced: true 表示被 replace 语义替换)
  • oas-crop:裁剪确认,detail: { file, blob }(file 为原文件,blob 为离屏 canvas 裁剪结果)

方法:submit()(手动上传)、startUpload()(等价)、abort(file?)(取消单个/全部进行中的上传)。

oas-progress 进度反馈

第三方组合场景 ​

以下场景不进组件 API,经既有通道组合达成:

js
// 大文件分片 / 对象存储直传:custom-request 接管(分片策略是业务决策)
el.customRequest = async ({ file, onProgress, onSuccess, onError }) => {
  const chunks = sliceFile(file, 5 * 1024 * 1024) // 自行分片
  for (let i = 0; i < chunks.length; i++) {
    await uploadChunk(chunks[i], i)
    onProgress({ percent: ((i + 1) / chunks.length) * 100 })
  }
  onSuccess(await assembleChunks(file))
}
  • 头像裁剪:内建 crop 通道覆盖(见「图片裁剪」节);需接第三方裁剪库时可改用 before-upload 返回裁剪后的新 File
  • 上传列表拖拽排序:item 插槽自定义行 + 宿主接第三方 dnd 库重排 files
  • 圆形头像卡:CSS 变量 --oas-upload-card-radius: 50%(不占独立枚举)

required 必填 ​

required 必填(原生校验链)

required 驱动原生校验链(form-associated):未填时 checkValidity() 为 false(valueMissing),原生表单提交被阻止;填写后自动恢复 :valid。

当前表单值可经公开 value property 读/写:el.value 返回可提交的 File 数组({name,url} 回显记录无文件体、不计入),无文件时为空数组;el.value = [file] 整体替换文件列表(走 files property 同款受控通道,不派发事件)。

API ​

oas-upload ​

属性 ​

属性说明类型默认值
accept接受的文件类型string—
action上传接口 URL(真实 XHR 通道;不配且无 customRequest 时为模拟进度)string—
auto-upload添加后自动模拟上传boolean—
crop图片上传前裁剪(picture/picture-card + accept 含图片时生效):选择后弹内建裁剪对话框,确认以 canvas 裁剪结果入列boolean—
crop-aspect裁剪固定宽高比(如 1:1、16:9);非法/缺省为自由比例string—
data附加表单字段(JSON 字符串,随文件一起提交)——
directory目录上传(整目录递归入列)boolean—
disabled禁用boolean—
headers附加请求头(JSON 字符串)——
list-type列表样式:list(默认)/ picture(列表带小缩略图)/ picture-card(卡片缩略图墙)stringlist
max最大文件数string0
max-size单文件大小上限(字节或 2KB/1MB/1GB;超限派 oas-exceed size 形态)string—
methodHTTP 方法(默认 POST)stringPOST
multiple多选boolean—
name上传文件的表单字段名(默认 file)string—
paste粘贴上传(默认关;开启后粘贴剪贴板文件入列)boolean—
replacemax-count=1 时替换语义(新文件替换旧文件而非拒绝)boolean—
required必填标记(驱动原生校验链 valueMissing;不透传内层控件)boolean—
show-file-list文件列表显隐("false" 隐藏,仅保留拖拽区)stringtrue
tip拖拽区提示文案(同 template[slot="tip"] 富内容)string—
with-credentials跨域携带凭证boolean—

Property(JS property;是否写回 attribute 见各行说明) ​

Property说明类型默认值
files受控文件列表(property 通道,写回即同步渲染)Array<File | UploadEchoFile>[]
value当前值:可提交的 File[](仅文件体条目;回显记录不含文件体、不计入)File[] | null[]

事件 ​

事件说明
oas-cancel取消上传,detail: { file }(行/卡片 cancel 按钮)
oas-change文件列表变化,detail: { files }
oas-crop裁剪确认时派发,detail: { file, blob }(file 原文件,blob 裁剪结果)
oas-error上传失败,detail: { file, response?, status? }(行/卡片出重试按钮)
oas-exceed【兼容别名】等价 oas-exceed-limit;后续版本移除,detail: { files: rejected, max, total: next.length } | { files: sizeRejected, type: 'size', maxSize, total: next.length }
oas-exceed-limit添加文件超限被拒绝(规范名,对齐 checkbox-group/select/toggle-group),detail: { files, max, total };数量/大小超限均派发(大小超限额外带 type: 'size' 与 maxSize)
oas-preview打开预览浮层,detail: { file, url }
oas-progress上传进度回调,detail: { file, percent }(真实/模拟/custom-request 均派发,成功收尾 100)
oas-remove移除文件,detail: { file, index }
oas-retry点击重试,detail: { file }(失败后重发)
oas-success上传成功,detail: { file, response }
oas-upload上传进度,detail: { file, percent, status }

插槽 ​

名称说明
template[slot="item"]自定义文件行/卡片([data-item-name]/[data-item-size] 绑定)
template[slot="tip"]拖拽区提示富内容(tip 属性优先)
template[slot="trigger"]自绘触发区模板(native slot 对 template 元素不生效,走克隆通道;zone 点击仍打开文件选择)
trigger替换拖拽区内容(zone 语义保留)

CSS 变量 ​

CSS 变量默认值
--oas-upload-card-radiusvar(--oas-radius-md)

⚠️ template[slot="trigger"] 的三个限制:① 模板内容克隆进 shadow DOM——宿主页面样式表对克隆内容不生效(样式用内联样式 / oas 组件 / CSS 变量解决);② 克隆是组件 update() 时的静态快照——模板连接后再变更不会自动刷新(写完模板再挂组件,或之后改任意属性触发一次 update 重同步);③ cloneNode 不携带事件监听器——宿主绑在模板节点上的 @click / addEventListener 在克隆里失效,交互请走组件事件(oas-change 等)或在克隆后的 zone 容器上委托绑定。

键盘:拖拽区 Enter / 空格 打开文件选择;删除按钮可聚焦;预览浮层 Esc 关闭。

基于 MIT OR Apache-2.0 双许可发布