更新记录
1.0.0(2026-10-13)
下载此版本
- 首个发布版本:跨端通用文件上传组件
- 支持 APP(Android / iOS / 鸿蒙)、H5、小程序
- APP 端提供「拍照 / 相册选择图片 / 选择文件」统一选择入口:
accept="all" → 拍照 / 相册选择图片 / 选择文件
accept="image" → 拍照 / 从相册选择
- 其它类型 → 直接调起原生文件选择器
- 鸿蒙端基于 DocumentViewPicker 原生选文件(复制到应用沙盒后回传本地路径)
- UI 与逻辑彻底解耦:支持
#default / #item 作用域插槽自定义
- 内置能力:上传队列、进度回显、失败重试、文件大小 / 数量限制、手动接管上传(
autoUpload=false)
平台兼容性
uni-app(4.57)
| Vue2 |
Vue3 |
Chrome |
Safari |
app-vue |
app-nvue |
Android |
iOS |
鸿蒙 |
| × |
√ |
√ |
√ |
√ |
- |
5.0 |
12 |
√ |
| 微信小程序 |
支付宝小程序 |
抖音小程序 |
百度小程序 |
快手小程序 |
京东小程序 |
鸿蒙元服务 |
QQ小程序 |
飞书小程序 |
小红书小程序 |
快应用-华为 |
快应用-联盟 |
| √ |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
uni-app x(5.05)
| Chrome |
Safari |
Android |
iOS |
鸿蒙 |
微信小程序 |
| √ |
√ |
5.0 |
12 |
√ |
√ |
其他
| 多语言 |
暗黑模式 |
宽屏模式 |
蒸汽模式 |
| × |
× |
√ |
× |
jq-upload(跨端文件上传组件)
📦 更新记录
1.0.0(2026-10-13)
跨端通用上传组件首个发布版本(详见 changelog.md)
🌐 平台兼容性
uni-app(5.12)
| Vue2 |
Vue3 |
Chrome |
Safari |
app-vue |
app-nvue |
Android |
iOS |
鸿蒙 |
| √ |
√ |
√ |
√ |
√ |
- |
4.4 |
12 |
√ |
| 微信小程序 |
支付宝小程序 |
抖音小程序 |
百度小程序 |
快手小程序 |
京东小程序 |
鸿蒙元服务 |
QQ小程序 |
飞书小程序 |
小红书小程序 |
快应用-华为 |
快应用-联盟 |
| √ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
uni-app x(5.12)
| Chrome |
Safari |
Android |
iOS |
鸿蒙 |
微信小程序 |
| - |
- |
- |
- |
- |
- |
其他
🎯 核心特性
- UI 与逻辑彻底解耦:使用 Vue3 作用域插槽 (Scope Slot) 进行 UI 控制,如果不传插槽,默认提供极简的回显和上传按钮。
- 匹配所有平台:APP + H5 + 小程序,其中 APP 端 Android / iOS / 鸿蒙 均已适配。
- APP 端统一选择入口:
accept="all":弹出「拍照 / 相册选择图片 / 选择文件」;
accept="image":弹出「拍照 / 从相册选择」;
- 其它类型:直接调起原生文件选择器。
- 鸿蒙原生文件选择:基于 DocumentViewPicker 选择文件并复制到应用沙盒后回传本地路径。
💻 基本用法
1. 使用默认 UI
<template>
<jq-upload
v-model="fileList"
action="https://xxx.com/api/upload"
:headers="{ token: '123' }"
@success="handleSuccess"
/>
</template>
<script setup>
import { ref } from "vue";
const fileList = ref([]);
const handleSuccess = ({ file, response }) => {
console.log("上传成功", response);
};
</script>
2. 自定义 UI
通过 #item 和 #default 插槽渲染。
<template>
<jq-upload v-model="fileList" action="https://xxxx.com/api/upload" accept="image">
<!-- 1. 定制文件列表展示 -->
<template #item="{ file, index, deleteItem }">
<view class="my-custom-file">
<image :src="file.url" mode="aspectFill"></image>
<text>进度: {{ file.progress }}%</text>
<button size="mini" @click="deleteItem">删除</button>
</view>
</template>
<!-- 2. 定制触发上传按钮 -->
<template #default="{ disabled, triggerPick }">
<button :disabled="disabled" type="primary" @click="triggerPick">点击上传图片</button>
</template>
</jq-upload>
</template>
3. 完全手动控制上传 (复杂业务逻辑)
当你的业务有极其复杂的上传流程(如需要先算 MD5、处理秒传逻辑、或者分片上传)时,可以关闭自动上传,通过监听 @change 手动接管。
<template>
<jq-upload v-model="fileList" :autoUpload="false" @change="onChange">
<!-- 这里同样可以像上面一样完全自定义 UI -->
</jq-upload>
</template>
<script setup>
import { ref } from "vue";
const fileList = ref([]);
const onChange = (newList) => {
// 找出刚刚由 jq-upload 加入队列,状态为 pending 的新文件
const pendingFiles = newList.filter((f) => f.status === "pending");
pendingFiles.forEach(async (file) => {
// 1. 手动标记为上传中,UI 也会跟着转圈圈
file.status = "uploading";
// 2. 走你自己的复杂上传逻辑 (比如 uni.uploadFile 或者云储存 SDK)
try {
const res = await myCustomUploadLogic(file.url);
file.status = "success";
file.url = res.serverUrl; // 回填服务器地址
} catch (err) {
file.status = "failed";
}
});
};
</script>
🛠 参数说明 (Props)
| 参数名 |
类型 |
默认值 |
说明 |
v-model |
Array |
[] |
组件绑定的标准文件列表数据 |
action |
String |
'' |
上传的接口地址(当 autoUpload 为 true 时必填) |
headers |
Object |
{} |
请求头(例如可以携带 Token) |
formData |
Object |
{} |
额外的 formData 业务参数 |
name |
String |
'file' |
发送到后端的 file 对应的 key 名称 |
accept |
String |
'all' |
允许的文件类型:image | video | file | all |
multiple |
Boolean |
true |
是否允许多选 |
limit |
Number |
9 |
最大上传文件数量 |
maxSize |
Number |
MAX_VALUE |
单个文件体积上限 (单位:MB) |
autoUpload |
Boolean |
true |
是否在选中文件后立刻自动触发上传 |
disabled |
Boolean |
false |
是否禁用组件 |
showItemList |
Boolean |
true |
是否展示内置文件列表(设为 false 后完全由 #item 插槽接管) |
说明:v-model 对应组件内部 modelValue;当 autoUpload=false 时需自行监听 @change 并处理上传,action 可不填。
⚡ 事件说明 (Events)
| 事件名 |
参数 |
说明 |
@change |
(fileList) |
绑定的文件列表发生变化时触发(选中、删除、状态变化) |
@success |
({ file, response, index }) |
单个文件上传成功时触发,response 为服务端返回结果 |
@error |
({ file, error, index }) |
单个文件上传失败时触发 |
@delete |
({ file, index }) |
用户主动删除某个文件时触发 |
@oversize |
(file) |
当选择的文件超出 maxSize 限制时触发 |
@upload-all-complete |
(fileList) |
手动批量上传全部结束时触发(autoUpload=false 场景) |
🧩 插槽说明 (Slots)
| 插槽名 |
作用域参数 |
说明 |
#default |
{ disabled, triggerPick } |
自定义上传触发区域 |
#item |
{ file, index, deleteItem, preview, retry } |
自定义单个文件列表项 |
🔧 Expose 暴露方法
如果希望在外部利用 ref 使用:
triggerPick(): 主动调起底层设备的文件选择弹窗。
deleteItem(index): 手动删除指定索引的文件。
retryUpload(index): 重试指定索引的失败文件。
startUploadAll(): 手动批量上传所有待上传/失败文件。
fileList: 当前文件列表(响应式)。
hasPending: 是否存在待上传/失败文件(响应式)。