Skip to content

n-upload 文件上传 ​

九宫格图片 / 视频列表:选择(相册 / 拍摄,数量 / 大小 / 扩展名校验)→ 上传 → 地址回填 → 点击预览 → 删除。

  1. 上传双模式:action 非空 = 自动模式(选完即调 uni.uploadFile,name / header / formData 透传,进度百分比 + 进度条、失败重试 UI 内置;auto-upload=false 改为选完入列、ref 统一触发);action 空串 = 手动模式(afterRead 交业务上传,经 ref 的 setProgress / result / fail 回报进度与结果)
  2. 地址回填双通道:自动模式 HTTP 成功后按「data 字符串直取 → 顶层 url → data.url」自动解析返回体,命中即零配置回填;未命中(或手动模式)由业务在 success / afterRead 里调 result(url, index) 显式回填——未回填的文件不进入 modelValue
  3. modelValue 恒为 string[](已回填地址的文件列表);头像等单文件场景传 max-count=1 后取首项;外部赋值即重置初始列表
  4. 校验内建:max-count 数量、max-size 单文件大小(MB)、extension 扩展名白名单;被拒文件派发 exceed / oversize 事件并轻提示(文案多语言)
  5. 图片点击走系统全屏预览(preview 可关);视频无平台缩略图,深底图标 + 播放角标呈现,点击只派发 preview 事件由业务接管播放

平台兼容性 ​

App H5 微信小程序 支付宝小程序 百度小程序 头条小程序 QQ小程序
√ √ √ × × × ×

API ​

属性 ​

参数 说明 类型 默认值 可选值
model-value 已回填地址的文件列表(string[],配合 @update:model-value 双向绑定);上传回填 / 删除时更新,外部赋值即重置初始列表 Array [] -
action 上传接口地址;空串 = 手动模式(afterRead 交业务上传,经 ref 回报结果),非空 = 自动调 uni.uploadFile String "" -
name 上传接口的文件字段名(uni.uploadFile 的 name 参数) String "file" -
header 上传接口的请求头(如鉴权 token) Object null -
form-data 上传接口附带的表单数据 Object null -
accept 媒体类型:image 图片(可多选)/ video 视频(单选) String image image / video
max-count 最大文件数;0 / -1 不限(单次选择仍封顶 9,平台限制);达到上限隐藏加号格 Number 9 -
max-size 单文件大小上限(MB);0 不限;超限文件被拒并派发 oversize + 轻提示 Number 0 -
extension 允许的扩展名白名单(按文件路径后缀匹配,不区分大小写);空数组不限;不匹配的文件被拒并轻提示 Array [] -
size-type 图片压缩方式(uni.chooseImage 的 sizeType):original 原图 / compressed 压缩图 Array ["original","compressed"] -
source-type 选择来源:album 相册 / camera 拍摄 Array ["album","camera"] -
compressed 是否压缩所选视频(仅 accept="video" 生效) Boolean true -
camera 拍摄视频的摄像头(仅 accept="video" 且 sourceType 含 camera 时生效) String back back / front
max-duration 拍摄视频最长时长秒(仅 accept="video" 生效) Number 60 -
auto-upload 自动模式下选完即传;false = 选完仅入列(待传态),经 ref.upload() 统一触发 Boolean true -
use-before-read 选择文件返回后先派发 beforeRead,由业务 callback 决定是否继续校验入列(异步前置拦截:查重 / 鉴权 / 内容审核等内建校验覆盖不了的场景) Boolean false -
disabled 禁用:拦截选择与删除(保色相降透明),已选文件仍可预览 Boolean false -
deletable 显示每格右上角删除按钮;false = 只能看不能删 Boolean true -
confirm-delete 删除前弹系统确认框(文案走多语言) Boolean false -
preview 点击已选图片调用系统全屏预览(预览范围为列表内全部图片;视频恒走 preview 事件由业务接管) Boolean true -
preview-image 展示列表内缩略图;关闭时数据、校验和上传保留,独立于 preview 全屏预览 Boolean true -
show-progress 上传中显示进度百分比 + 进度条;false 显示加载圈 Boolean true -
width 格子宽度:数值 px 或任意 css 长度("30%" 等) String / Number 80 -
height 格子高度:数值 px 或任意 css 长度 String / Number 80 -
radius 格子圆角:数值 px 或任意 css 长度;空串取主题令牌(--n-upload-radius,默认 8px) String / Number "" -
gutter 格子间距(px,作用于每格右侧与下侧) Number 8 -
image-mode 已选文件的缩放模式(image 原生 mode 子集):aspectFill 短边铺满居中裁剪 / aspectFit 完整显示留白 / scaleToFill 拉伸铺满 String aspectFill aspectFill / aspectFit / scaleToFill
upload-icon 加号格图标名(n-icon 名称表) String plus -
upload-text 加号格图标下方的说明文字(如 "上传照片");空串不显示 String "" -
upload-icon-color 加号格图标颜色(任意 CSS 色值);空串取次要文字色(随主题) String "" 与 css 相同
custom-class 挂到根节点的额外 class(类需定义在组件样式表内) String "" -
custom-style 根节点行内样式 String "" 与 css 相同

事件 ​

事件名 说明 回调参数
update:model-value 已回填地址的文件列表变化(v-model 通道) urls: string[]
change 与 update:modelValue 同参同发 urls: string[]
before-read 选择返回后、校验入列前触发(use-before-read 开启时);callback(false) 丢弃本次选择(提示业务自理) { files, callback }(files: NUploadFileItem[],index 恒 -1 = 尚未入列;callback: (ok: boolean) => void,异步回执有效)
after-read 新选文件全部通过校验并入列后触发(手动上传模式由此接管) files: NUploadFileItem[](index / path / size / name / duration)
success 单个文件上传完成(自动模式 = HTTP 成功;手动模式 = result() 回填) { index, url, filePath, response }(url 为自动解析结果,未命中为空串;response 为返回体原文,手动模式为空串)
error 单个文件上传失败(选择器调用失败 index 为 -1;用户取消选择不派发) { index, filePath, errMsg }
progress 上传进度更新 { index, progress }(0-100)
exceed 选择数量超出 max-count 被拒 files: NUploadFileItem[](被拒部分)
oversize 文件超过 max-size 被拒 files: NUploadFileItem[](被拒部分)
delete 删除文件后触发 { index, url }(url 为已回填地址,未回填为空串)
preview 点击文件时触发(图片默认同时调系统全屏预览;失败态点击走重试不派发);视频由此接管播放 { index, url }

方法(ref 直调) ​

实例通过 ref 直接调用下列公开方法;组件专属实例类型须通过目标 Android 编译验证:

方法 说明 参数
choose 选择文件;-1 新增、有效下标替换;取消、失败或校验不通过保留旧项;禁用/目标上传中拦截 (index: number = -1)
upload 触发上传全部待传 / 失败文件(action 非空时有效;失败项一并重试) 无
result 回填上传结果:url 就位即 success 并计入 modelValue(重复回填同值不重复派发) (url: string, index: number)
fail 手动上传回报失败:对应格转入失败态(自动模式有 action 时点格即可重试) (index: number)
setProgress 手动上传回报进度:对应格转入上传中并显示进度,与自动模式同派 progress 事件 (progress: number, index: number)

插槽 ​

插槽名 说明
add 自定义加号格内容(默认渲染 n-icon 图标 + 可选文字)

实现说明 ​

选择与呈现机制对照 ​

机制 参考做法 本组件选择与理由
外部入口 实例方法选择文件 choose(index=-1) 公开同一选择管线;-1 新增,已有下标替换;仍执行数量、类型和大小校验。
替换 选择成功后替换指定项 校验通过才替换,取消或失败保留旧文件;稳定 uid 防止列表变动后写错位置。
缩略图 列表展示与全屏预览分开开关 previewImage 只控制媒体缩略图,文件格、进度、错误、重试和删除保持可用;preview 控制点击后的全屏预览。
  • 机制对照(参考做法 vs 本库做法):
    • 值模型:参考源取 string / string[] 双形态(随 multiple 切换)或 fileList 内部态 + urls 双轨。本库统一 modelValue: string[](已回填地址),单文件场景由 max-count=1 表达——与 n-picker 全模式 string[] 的库内惯例一致,避免"同名 prop 改变值类型"的隐式契约;multiple prop 不收(max-count=1 即单选,语义被全覆盖)。
    • 地址解析:参考源要么绑自家后端格式、要么全靠业务在 success 里回填。本库取两层:常见返回体(data 直串 / url / data.url)自动解析零配置回填,未命中走 ref.result() 显式回填(业务回填通道全保留),两种格式都完整进入 modelValue。
    • 上传编排:手动 / 自动双模式 + auto-upload 开关 + ref.upload() 批量触发 + 失败点格重试,取各参考源并集;删除在上传中拦截(轻提示),删除前可选系统确认。
    • 进度视觉:百分比文字 + 底部细进度条(show-progress 关闭换加载圈);不依赖 n-progress(未交付组件),条宽由行内样式驱动。
    • 视频呈现:uni-app x 的 chooseVideo 不返回缩略图(GetVideoInfo 才有),深底 + 视频图标 + 播放角标占位,点击只派发 preview 事件由业务接管播放;图片点击走系统全屏预览(预览列表 = 列表内全部图片,本地临时路径与已回填地址均可)。
    • 点击已选项替换(少数参考源的交互)不收:与"点图预览"手势冲突,误触率高,从使用者视角择预览。
  • 参考并集缺口裁决(cl / un / fui / 旧库四源实读对照,逐项取舍):
    • useBeforeRead + beforeRead 收编:选择返回后、内建校验前的异步前置拦截(查重 / 鉴权 / 内容审核)——此前业务无法在入列前拒收文件,为真实能力缺口;回执 callback(ok) 与参考源同构,index 恒 -1(尚未入列,与选择器失败载荷同语义)。
    • multiple 不收(cl / un 均有):max-count=1 即单选,值模型恒 string[] 不随开关变形,语义被全覆盖。
    • capture 不收(un 有):与 sourceType 同义(album / camera 拾取模式),本库命名与平台 API 参数一致。
    • compressImage / compressOptions 不收(un 有):图片深度压缩参数跨端实现差异大(H5 走 canvas 且有压缩后上传丢原文件名的已知缺陷,官方文档自载),平台原生开关(sizeType / compressed)已收录,深度压缩由业务在 afterRead 拿到路径后自理。
    • round 不收(un 有):radius 全覆盖("50%" / 999px 即圆),不设同义快捷 prop。
    • bgColor 不收(un easycom 有、其文档 API 表未载):加号格底色定制——#add 插槽内容铺满格子即可自带底色,观感统一优先走主题令牌。
    • accept="file" 不收(un 有):平台 API 缺失——uni.chooseFile 仅 H5 可用、App 端无官方文件选择 API、微信端为 chooseMessageFile(聊天文件,语义不同),无法跨端收编。
    • #file 逐格作用域插槽不收(un 有):逐格全接管会绕开内置状态机(进度 / 失败重试 / 删除角标),组件核心价值即状态机;需要完全自定义展示的业务用 #add + afterRead 自管列表。
    • fileList 状态预设(uploading / reload / error 初始态,un 有)不收:值模型统一受控单轨(modelValue: string[],外部赋值即全部按已完成渲染);编辑场景回显失败态可由业务对初始项调 fail() / setProgress() 置态。
    • isAdd / addSize / borderColor / borderStyle 不收(fui 有):纯展示已有列表归 n-image / n-album 组件族;加号图标尺寸与边框样式经 #add 插槽全量接管,观感统一走主题令牌。
  • 状态机:每文件 pending(纯图可见)→ uploading(深色遮罩 + 进度)→ success(透明覆盖层)/ error(警示 + 重新上传,点格重试)。覆盖层常驻铺满、按「状态 + 删除钮 / 重试钮 / 进度形态」装配 key 整层销毁重建(App 端子节点插拔不重绘铁律);进度数值不入 key,同状态内仅行内宽度更新。
  • 下标稳定性:上传闭包持有文件对象引用、按 uid 重定位下标——上传中删除其它文件导致列表偏移不会错写;事件与 ref 方法携带的下标以调用时刻的实际位置为准。
  • 校验与反馈:数量 / 大小 / 扩展名逐项校验,被拒文件按原因分组派发(exceed / oversize)并按首个命中原因轻提示(文案走多语言);扩展名不匹配仅轻提示(不设独立事件,参考源同款处理)。用户取消选择不派发 error。
  • 外部赋值语义:modelValue 与当前已回填列表比对,不同即整表重建(初始 / 重置),进行中的上传项被丢弃(受控重置语义);组件卸载后网络回调静默丢弃,不再派发事件。
  • 主题令牌:--n-upload-radius(格子圆角)、--n-upload-mask-color(上传中 / 失败遮罩)、--n-upload-video-bg / --n-upload-play-bg(视频占位)、--n-upload-bar-height / --n-upload-bar-track(进度条)、--n-upload-del-size / --n-upload-del-bg(删除钮)、--n-upload-disabled-opacity(禁用透明)、--n-upload-text-size(加号文字);进度条填充色取品牌色令牌随主题。加号格图标尺寸为常量(与 $n-upload-icon-size 令牌默认值联动,见 variable.scss 注释)。

记录 · 思考 · 创作