更新记录
1.0(2026-09-16)
1.0
基于 uni-app(Vue 3)的文件分片上传组件,支持图片/视频选择、并发分片上传、进度展示、失败重试
平台兼容性
uni-app(5.24)
| Vue2 |
Vue3 |
Chrome |
Safari |
app-vue |
app-nvue |
Android |
iOS |
鸿蒙 |
| - |
√ |
√ |
√ |
√ |
- |
- |
- |
- |
| 微信小程序 |
支付宝小程序 |
抖音小程序 |
百度小程序 |
快手小程序 |
京东小程序 |
鸿蒙元服务 |
QQ小程序 |
飞书小程序 |
小红书小程序 |
快应用-华为 |
快应用-联盟 |
| - |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
chunk-upload 分片上传组件使用说明
基于 uni-app(Vue 3)的文件分片上传组件,支持图片/视频选择、并发分片上传、进度展示、失败重试,符合 easycom 规范(components/chunk-upload/chunk-upload.vue),无需手动注册即可在页面中直接使用。
一、快速开始
<template>
<view class="page">
<chunk-upload
chunk-url="https://api.example.com/upload/chunk"
merge-url="https://api.example.com/upload/merge"
:limit="5"
:chunk-size="4 * 1024 * 1024"
:media-type="['image', 'video']"
:header="{ Authorization: 'Bearer xxx' }"
@success="onSuccess"
@fail="onFail"
/>
</view>
</template>
<script>
export default {
methods: {
onSuccess({ file, url }) {
console.log('上传成功:', file.name, url);
},
onFail({ file, msg }) {
console.log('上传失败:', file.name, msg);
}
}
};
</script>
项目启用 easycom 时(uni-app 默认开启),组件放在 components/chunk-upload/chunk-upload.vue 即可自动注册;未启用时需手动 import 并注册。
二、Props
| 属性 |
类型 |
必填 |
默认值 |
说明 |
| chunkUrl |
String |
是 |
- |
分片上传接口地址 |
| mergeUrl |
String |
是 |
- |
合并文件接口地址 |
| limit |
Number |
否 |
9 |
最多可上传的文件数量 |
| chunkSize |
Number |
否 |
2 * 1024 * 1024 |
分片大小(字节),默认 2MB |
| mediaType |
Array |
否 |
['image', 'video'] |
允许选择的文件类型,可选值 image / video |
| header |
Object |
否 |
{} |
附加到上传/合并请求的自定义请求头(如 token) |
mediaType 分派逻辑:
- 仅
image:调用 uni.chooseImage
- 仅
video:调用 uni.chooseVideo
- 混合:优先
uni.chooseMedia,不支持时降级 uni.chooseFile
三、Events
| 事件 |
参数 |
触发时机 |
| success |
{ file, url } |
所有分片上传成功且合并成功;url 为后端合并接口返回的最终文件地址 |
| fail |
{ file, msg? } |
任一分片最终失败,或合并失败/合并请求失败 |
四、插槽
| 插槽名 |
说明 |
| trigger |
自定义上传触发区域,不传时显示默认的"点击上传文件"样式 |
<chunk-upload chunk-url="..." merge-url="...">
<view class="my-btn">选择文件并上传</view>
<!-- 也可使用 <template #trigger> 包裹 -->
</chunk-upload>
五、上传流程
- 选择文件(按
mediaType 分派选择 API,保留 size、文件名)。
- 计算分片数:
Math.ceil(file.size / chunkSize),size 为 0 时按 1 片。
- 并发上传分片(最多 3 个并发),每完成一片更新进度条。
- 全部分片成功后调用合并接口,状态流转:
等待上传(pending) → 上传中(uploading) → 合并中(merging) → 上传成功(success)
↘ 上传失败(fail) → 可重试/删除
六、后端接口约定
1. 分片接口 chunkUrl
- 请求方式:
POST(multipart/form-data)
- 请求字段:
| 字段 |
类型 |
说明 |
| file |
File |
文件内容(见下方"重要说明") |
| chunkIndex |
Number |
分片索引,从 0 开始 |
| totalChunks |
Number |
总分片数 |
| fileId |
String |
前端生成的文件唯一标识(UUID) |
| fileName |
String |
文件名 |
- 响应:JSON,
status === 1 表示成功,例如 { "status": 1, "message": "ok" }
2. 合并接口 mergeUrl
- 请求方式:
POST(application/json)
- 请求体:
{ "fileId": "xxx", "fileName": "xxx.jpg", "totalChunks": 3 }
- 响应:JSON,
status === 1 表示成功并返回最终地址:
{ "status": 1, "url": "https://cdn.example.com/files/xxx.jpg" }
若后端返回格式不是 status === 1,需调整组件中 uploadSingleChunk 与 mergeFile 的响应判断。
七、注意事项
- 当前为"逻辑分片"实现:每个分片请求实际上传的是整个文件(
filePath 相同),靠 chunkIndex/totalChunks 标识分片语义。生产环境中:
- H5 端建议基于 Web File API(
File.slice)实现真分片;
- 小程序/App 端需
FileSystemManager 分段读取或接入原生插件。
- Vue 3 响应式:组件内部已通过
this.fileList 中的代理对象进行状态更新,请勿在外部持有原始对象直接改写,否则视图不会更新。
- 进度条按"成功分片数 / 总分片数"计算,合并阶段进度恒为 100%。
- 失败重试会重置分片并重新走完整上传流程;删除仅移除列表项,如需清理后端临时分片请在
fail/删除逻辑中自行调用后端接口。
- 视频选择受平台限制(如
chooseVideo 一次只能选一个);混合选择的 count 参数在 chooseMedia 下可能不生效(微信端使用 maxCount)。
- 分片大小建议结合后端限制(如 nginx
client_max_body_size)调整,默认 2MB。