# 前端选择文件并上传
# 接口名:vk.chooseAndUploadFile
vk-unicloud 核心库版本 ≥ 2.25.1
通过 UI 界面选择文件(图片/视频/任意文件)并直接上传到云存储。
同时提供了选择回调事件 onChooseFile,方便对选择后的文件进行压缩、裁剪等二次处理,然后再上传。
内部基于 vk.uploadFile (opens new window) 实现,因此支持 vk.uploadFile 的全部上传能力(云存储供应商、云端目录、素材库保存等)。
# 平台兼容性
选择图片,type:'image' 与 选择视频,type:'video':全平台支持(App、H5、各家小程序)
选择任意文件,type:'all':仅 H5 和微信小程序支持(微信小程序仅支持选择聊天文件),其余平台会直接走 fail 回调
# 请求参数
# 选择相关参数
| 参数 | 说明 | 类型 | 默认值 | 可选值 |
|---|---|---|---|---|
| type | 文件类型(必填) | String | - | image、video、all |
| count | 最多可选择的文件数量(type 为 video 时无效,视频一次只能选 1 个) | Number | image 时 9,all 时 100 | - |
| extension | 文件后缀过滤(部分平台支持) | Array | - | - |
| sizeType | original 原图,compressed 压缩图,默认二者都有(仅 type 为 image 时生效) | Array | ['original','compressed'] | - |
| sourceType | album 从相册选图,camera 使用相机,默认二者都有(type 为 image、video 时生效) | Array | ['album','camera'] | - |
| compressed | 是否压缩所选的视频源文件(仅 type 为 video 时生效) | Boolean | true | false |
| camera | 摄像切换,front(前置摄像头)、back(后置摄像头)(仅 type 为 video 时生效) | String | back | front |
| maxDuration | 拍摄视频最长拍摄时间,单位秒(仅 type 为 video 时生效) | Number | 60 | - |
说明
- 选择视频时没有 count 参数,表现为一次仅能选择一个
- count 值在 H5 平台的表现基于浏览器本身的规范,只能限制单选/多选,并不能限制数量
# 上传相关参数(透传给 vk.uploadFile)
| 参数 | 说明 | 类型 | 默认值 | 可选值 |
|---|---|---|---|---|
| title | 上传时的 loading 提示语(多文件上传时全程只显示一次 loading) | String | - | - |
| provider | 云存储供应商,可选: unicloud 上传至空间内置存储 extStorage 上传至扩展存储 aliyun 上传至阿里云 oss | String | - | 见说明 |
| cloudDirectory | 指定上传后的云端目录 | String | - | - |
| needSave | 是否需要将文件信息保存到 admin 素材库 | Boolean | false | true |
| category_id | 素材库分类 id,当 needSave 为 true 时生效 | String | - | - |
| uniCloud | 上传到其他空间时使用,uniCloud 和 env 二选一即可 | cloud | - | - |
| env | 上传到其他空间时使用,uniCloud 和 env 二选一即可 | String | - | - |
| cloudPathAsRealPath | 阿里云目录支持,需 HBX3.8.5 以上版本才支持 | Boolean | true | false |
| cloudPathRemoveChinese | 删除文件名中的中文 | Boolean | true | false |
| errorToast | 异常时是否用 toast 代替 alert | Boolean | false | true |
| needAlert | 异常时是否需要 alert | Boolean | false | true |
注意:不支持顶层 cloudPath 参数(多文件上传时同一个 cloudPath 会互相覆盖)。如需为文件指定云端路径,有两种方式:
- 目录级:使用
cloudDirectory参数(文件名自动生成) - 文件级:在
onChooseFile回调中为每个 tempFile 单独设置cloudPath属性(见下方示例)
# 回调参数
| 参数 | 说明 | 类型 | 默认值 | 可选值 |
|---|---|---|---|---|
| onChooseFile | 选择文件后、上传前的回调,可对文件进行二次处理(见下方) | Function | - | - |
| onUploadProgress | 上传进度回调(见下方) | Function | - | - |
| success | 全部文件上传成功时,执行的回调函数 | Function | - | - |
| fail | 任一文件上传失败时,执行的回调函数 | Function | - | - |
| complete | 无论上传成功与否,都会执行的回调函数 | Function | - | - |
# 回调方法
# onChooseFile(res)
选择文件后的回调事件,方便对选择后的文件进行压缩、裁剪等二次处理,然后再上传。
res 结构如下
{
errMsg: 'chooseAndUploadFile:ok',
tempFilePaths: [], // 临时文件路径数组
tempFiles: [] // 临时文件组成的数组,每项含 path、name、size、fileType 等属性
}
2
3
4
5
如果 onChooseFile 回调有返回值(返回值不为 undefined),此返回值会用来替换实际选择的文件用以上传。可以在此回调内返回一个 Promise 来阻塞上传,在此期间对文件进行额外处理(如压缩、裁剪)。
替换后的 tempFiles 每项支持以下属性:
| 属性 | 说明 |
|---|---|
| path | 本地文件路径(必填) |
| cloudPath | 指定该文件上传后的云端路径(不指定会自动生成) |
| fileType | 文件类型 image/video/other。仅体现在返回结果的 tempFiles 项上,不影响上传行为(上传时框架始终按文件后缀自动推断) |
| name | 文件名(用于生成云端文件名及素材库记录) |
# onUploadProgress(res)
上传进度的回调,res 结构如下
{
index: 0, // 触发此回调的文件序号(从0开始)
loaded: 256, // 已上传大小
total: 1024, // 总大小
progress: 25, // 上传进度百分比(0-100)
tempFilePath: '', // 本地临时文件路径
tempFile: {} // 本地文件对象
}
2
3
4
5
6
7
8
# 返回值
成功回调(success / then)内的响应参数形式如下
{
errMsg: 'chooseAndUploadFile:ok',
tempFilePaths: [], // 本地临时文件路径组成的数组
tempFiles: [] // 文件对象数组,每项上都被追加了上传结果字段
}
2
3
4
5
tempFiles 每项在原有属性(path、name、size、fileType 等)基础上追加以下上传结果字段:
| 参数名 | 类型 | 说明 |
|---|---|---|
| url | string | 云端文件 URL,与 fileURL 一致 |
| fileID | string | 云端文件 ID |
| fileURL | string | 云端文件 URL |
| cloudPath | string | 云端文件路径 |
| provider | string | 本次上传的存储供应商 |
# 上传行为说明
- 顺序上传:多个文件按选择顺序逐个上传(与
uniCloud.chooseAndUploadFile的并发上传不同),控制台日志按文件依次输出,进度回调按 index 递进 - 失败即中断:任一文件上传失败时,中断后续文件的上传,整体走 fail 回调(reject)。err 对象上附加了以下字段,调用方可自行处理部分成功的文件:
{
// ...vk.uploadFile 的原始错误信息
index: 1, // 失败文件的序号
tempFilePath: '', // 失败文件的本地路径
tempFile: {}, // 失败文件对象
tempFiles: [] // 全部文件数组(序号小于 index 的文件已上传成功,其上有 url 等上传结果字段)
}
2
3
4
5
6
7
- 取消选择:用户取消选择文件时,直接走 fail 回调(errMsg 中含 cancel),不会弹出任何提示
# 示例
# 基础用法
// promise方式
vk.chooseAndUploadFile({
type: 'image',
count: 3,
title: '上传中...',
}).then((res) => {
console.log(res);
let urls = res.tempFiles.map((item) => item.url);
});
// callback方式,与promise方式二选一
vk.chooseAndUploadFile({
type: 'image',
count: 3,
title: '上传中...',
success: (res) => {
let urls = res.tempFiles.map((item) => item.url);
},
fail: (err) => {},
complete: () => {},
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 选择视频并上传
vk.chooseAndUploadFile({
type: 'video',
title: '上传中...',
success: (res) => {
let url = res.tempFiles[0].url;
},
});
2
3
4
5
6
7
# 选择任意文件并上传(仅 H5 和微信小程序)
vk.chooseAndUploadFile({
type: 'all',
count: 2,
title: '上传中...',
success: (res) => {
let urls = res.tempFiles.map((item) => item.url);
},
});
2
3
4
5
6
7
8
# 上传至指定云端目录 + 保存到素材库
vk.chooseAndUploadFile({
type: 'image',
count: 9,
title: '上传中...',
cloudDirectory: 'user-avatar', // 云端目录
needSave: true, // 保存到admin素材库
success: (res) => {},
});
2
3
4
5
6
7
8
# onChooseFile 二次处理(过滤文件 + 指定 cloudPath)
vk.chooseAndUploadFile({
type: 'image',
count: 9,
title: '上传中...',
onChooseFile: (res) => {
// 只保留第一个文件,并为其指定云端路径
let tempFiles = res.tempFiles.slice(0, 1);
tempFiles[0].cloudPath = `xx/test-${Date.now()}.png`;
// 支持返回Promise以阻塞上传(可在Promise内对图片进行压缩、裁剪等处理)
return {
tempFilePaths: res.tempFilePaths.slice(0, 1),
tempFiles,
};
},
success: (res) => {},
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 监听上传进度
vk.chooseAndUploadFile({
type: 'image',
count: 3,
onUploadProgress: (res) => {
let { index, progress } = res;
console.log(`第${index + 1}个文件当前进度:${progress}%`);
},
success: (res) => {},
});
2
3
4
5
6
7
8
9
# 常见问题
# 如何配置默认云存储供应商?
与 vk.uploadFile 一致,在 app.config.js 中配置 service.cloudStorage.defaultProvider 点击查看 (opens new window)
# 小程序上传提示域名不在白名单?
小程序需要配置上传域名白名单 点击查看 (opens new window)