目录

概念

1. web界面

2. 客户端API或组件上传

API

自定义样式

选择指定后缀图片,且限制选择个数

手动上传

 应用

3. 云函数上传文件到云存储

uni.chooseImage(OBJECT)

uni.previewImage(OBJECT)

uploadFile(Object object)

请求参数

响应参数

应用


概念

云存储提供稳定、安全、低成本、简单易用的云端存储服务,支持任意数量和形式的非结构化数据存储,例如图片、文档、音频、视频、文件等。

开发者使用uniCloud的云存储,无需再像传统模式那样单独去购买存储空间、CDN映射、流量采购等;

uniCloud的云存储分为内置存储和扩展存储:

  • 内置存储是serverless云厂商默认内置的存储方案,开通服务空间时默认开通,提供默认域名,操作简单;但资费较贵,部分云厂商的权限管理较弱;
  • 扩展存储是DCloud联合业内其它主流CDN厂商,扩展提供的uniCloud云存储方案,需开发者手动开通;但价格更便宜、功能更强大;

内置云存储的上传方式有3种:

  1. web界面:即在uniCloud控制台 web控制台,点击云存储,通过web界面进行文件上传。该管理界面同时提供了资源浏览、删除等操作界面。
  2. 客户端API或组件上传:在前端js中编写uniCloud.uploadFile,或者使用uni ui的FilePicker组件,文件选择+上传均封装完毕。
  3. 云函数上传文件到云存储:即在云函数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/valueArray\Object--组件数据,通常用来回显 ,类型由return-type属性决定 ,格式见下文
disabledBooleanfalse-组件禁用
readonlyBooleanfalse-组件只读,不可选择,不显示进度,不显示删除按钮
return-typeStringarrayarray/object限制 value 格式,当为 object 时 ,组件只能单选,且会覆盖
disable-previewBooleanfalse-禁用图片预览,仅 mode:grid生效
del-iconBooleantrue-是否显示删除按钮
auto-uploadBooleantrue-是否自动上传,值为false则只触发@select,可自行上传
limitNumber\String9-最大选择个数 ,h5 会自动忽略多选的部分
titleString--组件标题,右侧显示上传计数
modeStringlistlist/grid选择文件后的文件列表样式
file-mediatypeStringimageimage/video/all选择文件类型,all 只支持 H5 和微信小程序平台
file-extnameArray\String--选择文件后缀,字符串的情况下需要用逗号分隔(推荐使用字符串),根据 file-mediatype 属性而不同
list-stylesObject--mode:list 时的样式
image-stylesObject--mode:grid 时的样式
sizeTypeArray['original', 'compressed']'original', 'compressed'original 原图,compressed 压缩图,默认二者都有
sourceTypeArray['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',限定只选择 pngjpg后缀的图片

配置 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 参数说明

参数名类型必填说明平台差异说明
countNumber最多可以选择的图片张数,默认9见下方说明
sizeTypeArray<String>original 原图,compressed 压缩图,默认二者都有App、微信小程序、支付宝小程序、百度小程序
extensionArray<String>根据文件拓展名过滤,每一项都不能是空字符串。默认不过滤。H5(HBuilder X2.9.9+)
sourceTypeArray<String>album 从相册选图,camera 使用相机,默认二者都有。如需直接开相机或直接选相册,请只使用一个选项
cropObject图像裁剪参数,设置后 sizeType 失效App 3.1.19+
successFunction成功则返回图片的本地文件路径列表 tempFilePaths
failFunction接口调用失败的回调函数小程序、App
completeFunction接口调用结束的回调函数(调用成功、失败都会执行)

crop 参数说明

参数名类型必填说明平台差异说明
qualityNumber取值范围为1-100,数值越小,质量越低(仅对jpg格式有效)。默认值为80。
widthNumber裁剪的宽度,单位为px,用于计算裁剪宽高比。
heightNumber裁剪的高度,单位为px,用于计算裁剪宽高比。
resizeBoolean是否将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 返回参数说明

参数类型说明
tempFilePathsArray<String>图片的本地文件路径列表
tempFilesArray<Object>、Array<File>图片的本地文件列表,每一项是一个 File 对象

File 对象结构如下

参数类型说明
pathString本地文件路径
sizeNumber本地文件大小,单位:B
nameString包含扩展名的文件名称,仅H5支持
typeString文件类型,仅H5支持

示例

uni.chooseImage({
	count: 6, //默认9
	sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
	sourceType: ['album'], //从相册选择
	success: function (res) {
		console.log(JSON.stringify(res.tempFilePaths));
	}
});

uni.previewImage(OBJECT)

预览图片。

OBJECT 参数说明

参数名类型必填说明平台差异说明
currentString/Number详见下方说明详见下方说明
showmenuBoolean是否显示长按菜单,默认值为 true微信小程序2.13.0
urlsArray<String>需要预览的图片链接列表
indicatorString图片指示器样式,可取值:"default" - 底部圆点指示器; "number" - 顶部数字指示器; "none" - 不显示指示器。App
loopBoolean是否可循环预览,默认值为 falseApp
longPressActionsObject长按图片显示操作菜单,如不填默认为保存相册App 1.9.5+
successFunction接口调用成功的回调函数
failFunction接口调用失败的回调函数
completeFunction接口调用结束的回调函数(调用成功、失败都会执行)

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

参数名类型必填默认值说明平台差异说明
filePathString-要上传的文件对象-
cloudPathString-使用支付宝小程序云或腾讯云时,表示文件的绝对路径,包含文件名。
使用阿里云时,cloudPath为云端文件名,传cloudPathAsRealPath: true可以让cloudPath作为文件存储路径
-
cloudPathAsRealPathBooleanfalse是否以cloudPath作为云端文件绝对路径仅阿里云支持
fileTypeString--文件类型,支付宝小程序、钉钉小程序必填,可选image、video、audio-
onUploadProgressFunction-上传进度回调-

注意

  • 使用阿里云时,cloudPath为云端文件名,请勿使用非法字符
  • 支付宝小程序云与腾讯云cloudPath 为文件的绝对路径,包含文件名 foo/bar.jpg、foo/bar/baz.jpg 等,不能包含除[0-9 , a-z , A-Z]、/、!、-、_、.、、*和中文以外的字符,使用 / 字符来实现类似传统文件系统的层级结构。
  • 支付宝小程序云与腾讯云cloudPath为文件标识,相同的cloudPath会覆盖,如果没有权限覆盖则会上传失败。阿里云以自动生成的ID为文件标识,不会存在覆盖问题
  • 阿里云目前由于安全原因暂时禁止云存储内上传html文件
  • 上传文件超时时间可以在项目manifest.json内进行配置

响应参数
字段类型说明
fileIDString文件唯一 ID,用来访问文件,建议存储起来
requestIdString请求序列号,用于错误排查

应用

 

<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, //默认9
					sizeType: ['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>

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐