目录
概念
1. web界面
2. 客户端API或组件上传
API
自定义样式
选择指定后缀图片,且限制选择个数
手动上传
应用
3. 云函数上传文件到云存储
uni.chooseImage(OBJECT)
uni.previewImage(OBJECT)
uploadFile(Object object)
请求参数
响应参数
应用
概念
云存储提供稳定、安全、低成本、简单易用的云端存储服务,支持任意数量和形式的非结构化数据存储,例如图片、文档、音频、视频、文件等。
开发者使用
uniCloud
的云存储,无需再像传统模式那样单独去购买存储空间、CDN映射、流量采购等;
uniCloud
的云存储分为内置存储和扩展存储:
- 内置存储是serverless云厂商默认内置的存储方案,开通服务空间时默认开通,提供默认域名,操作简单;但资费较贵,部分云厂商的权限管理较弱;
- 扩展存储是DCloud联合业内其它主流CDN厂商,扩展提供的uniCloud云存储方案,需开发者手动开通;但价格更便宜、功能更强大;
内置云存储的上传方式有3种:
- web界面:即在uniCloud控制台 web控制台,点击云存储,通过web界面进行文件上传。该管理界面同时提供了资源浏览、删除等操作界面。
- 客户端API或组件上传:在前端js中编写
uniCloud.uploadFile
,或者使用uni ui的FilePicker组件,文件选择+上传均封装完毕。 - 云函数上传文件到云存储:即在云函数js中编写
uniCloud.uploadFile
注意:
- 前端和云函数端,均有一个相同名称的api:
uniCloud.uploadFile
。请不要混淆。 - 前端还有一个
uni.uploadFile
的API,那个API用于连接非uniCloud的上传使用。请不要混淆。 - 在使用腾讯云时如果访问云存储文件提示
The requested URL '/1123.jpg' was not found on this server
这种错误,一般是cdn流量用尽导致的,可以升级套餐或转为按量计费。 - 在允许用户上传图片的应用里,违规检测是必不可少的,为此uniCloud提供了内容安全检测模块,可以很方便的实现图片鉴黄等功能。详情参考:内容安全
1. web界面
即在uniCloud控制台 web控制台,点击云存储,通过web界面进行文件上传。该管理界面同时提供了资源浏览、删除等操作界面。
2. 客户端API或组件上传
在前端js中编写 uniCloud.uploadFile
,或者使用uni ui的 FilePicker组件,文件选择+上传均封装完毕
注意事项
为了避免错误使用,给大家带来不好的开发体验,请在使用组件前仔细阅读下面的注意事项,可以帮你避免一些错误。
- 组件需要依赖
sass
插件 ,请自行手动安装- 如不绑定服务空间,
autoUpload
默认为false
且不可更改- 选择文件目前只支持
H5
和微信小程序平台
,且微信小程序平台
使用wx.chooseMessageFile()
- v-model 值需要自动上传成功后才会绑定值,一般只用来回显数据
API
属性名 | 类型 | 默认值 | 可选值 | 说明 |
---|---|---|---|---|
v-model/value | Array\Object | - | - | 组件数据,通常用来回显 ,类型由return-type 属性决定 ,格式见下文 |
disabled | Boolean | false | - | 组件禁用 |
readonly | Boolean | false | - | 组件只读,不可选择,不显示进度,不显示删除按钮 |
return-type | String | array | array/object | 限制 value 格式,当为 object 时 ,组件只能单选,且会覆盖 |
disable-preview | Boolean | false | - | 禁用图片预览,仅 mode:grid 生效 |
del-icon | Boolean | true | - | 是否显示删除按钮 |
auto-upload | Boolean | true | - | 是否自动上传,值为false 则只触发@select,可自行上传 |
limit | Number\String | 9 | - | 最大选择个数 ,h5 会自动忽略多选的部分 |
title | String | - | - | 组件标题,右侧显示上传计数 |
mode | String | list | list/grid | 选择文件后的文件列表样式 |
file-mediatype | String | image | image/video/all | 选择文件类型,all 只支持 H5 和微信小程序平台 |
file-extname | Array\String | - | - | 选择文件后缀,字符串的情况下需要用逗号分隔(推荐使用字符串),根据 file-mediatype 属性而不同 |
list-styles | Object | - | - | mode:list 时的样式 |
image-styles | Object | - | - | mode:grid 时的样式 |
sizeType | Array | ['original', 'compressed'] | 'original', 'compressed' | original 原图,compressed 压缩图,默认二者都有 |
sourceType | Array | ['album', 'camera'] | 'album', 'camera' | album 从相册选图,camera 使用相机,默认二者都有。如需直接开相机或直接选相册,请只使用一个选项 |
自定义样式
配置 image-styles
属性,可以自定义mode:image
时的回显样式
配置 list-styles
属性,可以自定义mode:video|| mode:all
时的回显样式
<template><view><uni-file-picker fileMediatype="image" :image-styles="imageStyles"/><uni-file-picker fileMediatype="all" :list-styles="listStyles"/></view>
</template>
<script>export default {data() {imageStyles:{width:64,height:64,border:{color:"#ff5a5f",width:2,style:'dashed',radius:'2px'}},listStyles:{// 是否显示边框border: true,// 是否显示分隔线dividline: true,// 线条样式borderStyle: {width:1,color:'blue',radius:2}}}}
</script>
选择指定后缀图片,且限制选择个数
配置 file-mediatype
属性为 image
,限定只选择图片
配置 file-extname
属性为 'png,jpg'
,限定只选择 png
和jpg
后缀的图片
配置 limit
属性为 1 ,则最多选择一张图片
配置 mode
属性为 grid
,可以使用九宫格样式选择图片
<uni-file-picker v-model="imageValue" file-mediatype="image"mode="grid"file-extname="png,jpg":limit="1"@progress="progress" @success="success" @fail="fail" @select="select"
/>
手动上传
配置 auto-upload
属性为 false
,可以停止自动上传,通过ref
调用upload
方法自行选择上传时机
<template><view><uni-file-picker ref="files" :auto-upload="false"/><button @click="upload">上传文件</button></view>
</template>
<script>export default {data() {},methods:{upload(){this.$refs.files.upload()}}}
</script>
应用
<uni-file-picker v-model="imageValue" fileMediatype="image" mode="grid" @select="select" @progress="progress" @success="success" @fail="fail"
/>
<script>export default {data() {return {imageValue:[]}},methods:{// 获取上传状态select(e){console.log('选择文件:',e)},// 获取上传进度progress(e){console.log('上传进度:',e)},// 上传成功success(e){console.log('上传成功')},// 上传失败fail(e){console.log('上传失败:',e)}}}
</script>
3. 云函数上传文件到云存储
uni.chooseImage(OBJECT)
从本地相册选择图片或使用相机拍照。
OBJECT 参数说明
参数名 | 类型 | 必填 | 说明 | 平台差异说明 |
---|---|---|---|---|
count | Number | 否 | 最多可以选择的图片张数,默认9 | 见下方说明 |
sizeType | Array<String> | 否 | original 原图,compressed 压缩图,默认二者都有 | App、微信小程序、支付宝小程序、百度小程序 |
extension | Array<String> | 否 | 根据文件拓展名过滤,每一项都不能是空字符串。默认不过滤。 | H5(HBuilder X2.9.9+) |
sourceType | Array<String> | 否 | album 从相册选图,camera 使用相机,默认二者都有。如需直接开相机或直接选相册,请只使用一个选项 | |
crop | Object | 否 | 图像裁剪参数,设置后 sizeType 失效 | App 3.1.19+ |
success | Function | 是 | 成功则返回图片的本地文件路径列表 tempFilePaths | |
fail | Function | 否 | 接口调用失败的回调函数 | 小程序、App |
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
crop 参数说明
参数名 | 类型 | 必填 | 说明 | 平台差异说明 |
---|---|---|---|---|
quality | Number | 否 | 取值范围为1-100,数值越小,质量越低(仅对jpg格式有效)。默认值为80。 | |
width | Number | 是 | 裁剪的宽度,单位为px,用于计算裁剪宽高比。 | |
height | Number | 是 | 裁剪的高度,单位为px,用于计算裁剪宽高比。 | |
resize | Boolean | 否 | 是否将width和height作为裁剪保存图片真实的像素值。默认值为true。注:设置为false时在裁剪编辑界面显示图片的像素值,设置为true时不显示 |
Tips
- count 值在 H5 平台的表现,基于浏览器本身的规范。目前测试的结果来看,只能限制单选/多选,并不能限制数量。并且,在实际的手机浏览器很少有能够支持多选的。
- sourceType 值在 H5 平台根据浏览器的不同而表现不同,一般不可限制仅使用相册,部分浏览器也无法限制是否使用相机。
- 可以通过用户授权API来判断用户是否给应用授予相册或摄像头的访问权限uni.authorize(OBJECT) | uni-app官网
- App端如需选择非媒体文件,可在插件市场搜索文件选择,其中Android端可以使用Native.js,无需原生插件,而iOS端需要原生插件。
- 选择照片大多为了上传,uni ui封装了更完善的uni-file-picker组件,文件选择、上传到uniCloud的免费存储和cdn中,一站式集成。强烈推荐使用。
- App上有时会遇到图片旋转90度问题,插件市场有解决方案:图片旋转
- 微信小程序在2023年10月17日之后,使用API需要配置隐私协议
- 在部分低端机如红米上拍照闪退,拍照调用的是系统相机,当系统内存不足,rom为了给相机activity分配内存而把app的主activity回收了。遇到此问题建议使用nvue页面并内嵌的自定义相机的原生或uts插件。相关分析报告详见
注:文件的临时路径,在应用本次启动期间可以正常使用,如需持久保存,需在主动调用 uni.saveFile,在应用下次启动时才能访问得到。
success 返回参数说明
参数 | 类型 | 说明 |
---|---|---|
tempFilePaths | Array<String> | 图片的本地文件路径列表 |
tempFiles | Array<Object>、Array<File> | 图片的本地文件列表,每一项是一个 File 对象 |
File 对象结构如下
参数 | 类型 | 说明 |
---|---|---|
path | String | 本地文件路径 |
size | Number | 本地文件大小,单位:B |
name | String | 包含扩展名的文件名称,仅H5支持 |
type | String | 文件类型,仅H5支持 |
示例
uni.chooseImage({count: 6, //默认9sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有sourceType: ['album'], //从相册选择success: function (res) {console.log(JSON.stringify(res.tempFilePaths));}
});
uni.previewImage(OBJECT)
预览图片。
OBJECT 参数说明
参数名 | 类型 | 必填 | 说明 | 平台差异说明 |
---|---|---|---|---|
current | String/Number | 详见下方说明 | 详见下方说明 | |
showmenu | Boolean | 否 | 是否显示长按菜单,默认值为 true | 微信小程序2.13.0 |
urls | Array<String> | 是 | 需要预览的图片链接列表 | |
indicator | String | 否 | 图片指示器样式,可取值:"default" - 底部圆点指示器; "number" - 顶部数字指示器; "none" - 不显示指示器。 | App |
loop | Boolean | 否 | 是否可循环预览,默认值为 false | App |
longPressActions | Object | 否 | 长按图片显示操作菜单,如不填默认为保存相册 | App 1.9.5+ |
success | Function | 否 | 接口调用成功的回调函数 | |
fail | Function | 否 | 接口调用失败的回调函数 | |
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
current 参数说明
1.9.5+ 支持传图片在 urls 中的索引值
current 为当前显示图片的链接/索引值,不填或填写的值无效则为 urls 的第一张。App平台在 1.9.5至1.9.8之间,current为必填。不填会报错
注意,当 urls 中有重复的图片链接时:
- 传链接,预览结果始终显示该链接在 urls 中第一次出现的位置。
- 传索引值,在微信/百度/抖音小程序平台,会过滤掉传入的 urls 中该索引值之前与其对应图片链接重复的值。其它平台会保留原始的 urls 不会做去重处理。
举例说明:
一组图片 [A, B1, C, B2, D]
,其中 B1 与 B2 的图片链接是一样的。
- 传 B2 的链接,预览的结果是 B1,前一张是 A,下一张是 C。
- 传 B2 的索引值 3,预览的结果是 B2,前一张是 C,下一张是 D。此时在微信/百度/抖音小程序平台,最终传入的 urls 是
[A, C, B2, D]
,过滤掉了与 B2 重复的 B1。
uploadFile(Object object)
直接上传文件到云存储。
客户端上传文件到云函数、云函数再上传文件到云存储,这样的过程会导致文件流量带宽耗费较大。所以一般上传文件都是客户端直传。
请求参数
Object object
参数名 | 类型 | 必填 | 默认值 | 说明 | 平台差异说明 |
---|---|---|---|---|---|
filePath | String | 是 | - | 要上传的文件对象 | - |
cloudPath | String | 是 | - | 使用支付宝小程序云或腾讯云时,表示文件的绝对路径,包含文件名。 使用阿里云时, cloudPath 为云端文件名,传cloudPathAsRealPath: true 可以让cloudPath作为文件存储路径 | - |
cloudPathAsRealPath | Boolean | 否 | false | 是否以cloudPath 作为云端文件绝对路径 | 仅阿里云支持 |
fileType | String | - | - | 文件类型,支付宝小程序、钉钉小程序必填,可选image、video、audio | - |
onUploadProgress | Function | 否 | - | 上传进度回调 | - |
注意
- 使用阿里云时,
cloudPath
为云端文件名,请勿使用非法字符 - 支付宝小程序云与腾讯云
cloudPath
为文件的绝对路径,包含文件名 foo/bar.jpg、foo/bar/baz.jpg 等,不能包含除[0-9 , a-z , A-Z]、/、!、-、_、.、、*和中文以外的字符,使用 / 字符来实现类似传统文件系统的层级结构。 - 支付宝小程序云与腾讯云
cloudPath
为文件标识,相同的cloudPath
会覆盖,如果没有权限覆盖则会上传失败。阿里云以自动生成的ID为文件标识,不会存在覆盖问题 - 阿里云目前由于安全原因暂时禁止云存储内上传html文件
- 上传文件超时时间可以在项目manifest.json内进行配置
响应参数
字段 | 类型 | 说明 |
---|---|---|
fileID | String | 文件唯一 ID,用来访问文件,建议存储起来 |
requestId | String | 请求序列号,用于错误排查 |
应用
<template><view class="file"><view class="updateGroup"><view class="box" v-for="(item,index) in tempFile" :key="item.path"><image :src="item.path" mode="aspectFit" @click="previewImage(index)"></image><view class="close" @click="onClose(index)">x</view></view><view class="box add" @click="addFile" v-show="tempFile.length<maxSize"> + </view></view><button class="" @click="onUpdate">确认上传</button></view>
</template><script>export default {data() {return {tempFile: [],maxSize: 9,picArr: []};},methods: {// 选择本地文件addFile() {uni.chooseImage({count: 3, //默认9sizeType: ['compressed'], //可以指定是原图还是压缩图,默认二者都有success: res => {let oldFile = this.tempFile// 拼接let newFile = [...oldFile, ...res.tempFiles]// 最多展示最大数newFile = newFile.slice(0, this.maxSize)this.tempFile = newFile}})},// 删除onClose(index) {this.tempFile.splice(index, 1)},// 预览previewImage(index) {uni.previewImage({current: index, //current 为当前显示图片的链接/索引值,不填或填写的值无效则为 urls 的第一张urls: this.tempFile //需要预览的图片链接列表})},// 上传onUpdate() {let newsArr = this.tempFile.map(async item => {return await this.updateFunction(item)})console.log(newsArr);Promise.all(newsArr).then(res => {console.log("上传成功", res);this.picArr = res.map(item => item.fileID)console.log(this.picArr);}).catch(err => {console.log(err, '上传失败');})},// 批量上传到数据库updateFunction(item) {return uniCloud.uploadFile({filePath: item.path, //要上传的文件对象cloudPath: item.name, //cloudPath为云端文件名,})},}}
</script><style lang="scss" scoped>.updateGroup {padding: 30rpx;display: flex;flex-wrap: wrap;.box {width: 200rpx;height: 200rpx;background-color: #eee;margin-right: 15rpx;margin-bottom: 15rpx;position: relative;image {width: 100%;height: 100%;}.close {position: absolute;right: 0;top: 0;width: 50rpx;height: 50rpx;background: rgba(0, 0, 0, 0.7);color: #fff;border-radius: 0 0 0 80rpx;display: flex;justify-content: center;align-items: center;}}.add {font-size: 80rpx;display: flex;justify-content: center;align-items: center;color: #888;}}
</style>