暗黑模式
Uploader 上传器 1.0.18
手机扫码预览
23:37
组件名:rice-uploader
该组件用于上传图片、视频等文件场景。1.0.18 版本开始支持。
平台兼容性
uni-app x
| Android | iOS | 鸿蒙Next | 微信小程序 | h5 |
|---|---|---|---|---|
| √ | √ | √ | √ | √ |
基础用法
- 文件上传完毕后会触发
complete事件,可以拿到上传成功或者失败的文件信息。 - 如果传入了
successCode,则上传完成后,仅当返回的 HTTP状态码 与之相等才表示上传成功,未传值时,则不通过状态码进行比较,需自行通过 onSuccess回调函数进行判断 - 默认选择文件完成后会自动上传,如需手动上传,设置
auto-upload为false即可。
vue
<template>
<rice-uploader :action="action" :max-count="3" :success-code="200" @complete="onComolete" />
</template>
<script setup lang="ts">
import { UploaderFileItem, UploaderComplete } from "@/uni_modules/rice-ui"
const action = ref('https://api.riceui.cn/app/upload')
const onComolete = (filesList : UploaderFileItem[], result : UploaderComplete) => {
const fail = result.failList
const success = result.successList
console.log('filesList-->', filesList)
console.log('从filesList中拿上传成功合集:', filesList.filter(v => v.status == 'success'))
console.log('从result中拿上传成功合集:', success.map(v => v.file))
console.log('上传失败合集:', fail)
if (fail.length > 0) {
showToast(`${fail.map(v => v.errMsg).join('/')}`)
}
}
</script>文件预览
通过 v-model 可以绑定已经上传的文件列表,并展示文件列表的预览图。
vue
<template>
<!-- Android 端使用v-model时要手动 as UploaderFileItem[] -->
<rice-uploader v-model="(fileList2 as UploaderFileItem[])" :action="action" :max-count="3" :success-code="200"/>
</template>
<script setup lang="ts">
import { UploaderFileItem, UploaderComplete } from "@/uni_modules/rice-ui"
const action = ref('https://api.riceui.cn/app/upload')
const fileList2 = ref<UploaderFileItem[]>([
//如果 URL 中不包含类型信息,可以添加 fileType 标记来声明
{
url: 'https://riceui.oss-cn-hangzhou.aliyuncs.com/sky1.jpg',
// fileType:'image',
}, {
url: 'https://riceui.oss-cn-hangzhou.aliyuncs.com/flower2.jpg',
}])
</script>上传状态
通过 status 属性可以标识上传状态,uploading 表示上传中,failed 表示上传失败,success 表示上传完成。
vue
<template>
<!-- Android 端使用v-model时要手动 as UploaderFileItem[] -->
<rice-uploader v-model="(fileList3 as UploaderFileItem[])" :action="action"/>
</template>
<script setup lang="ts">
import { UploaderFileItem} from "@/uni_modules/rice-ui"
const action = ref('https://api.riceui.cn/app/upload')
const fileList3 = ref<UploaderFileItem[]>([{
url: 'https://riceui.oss-cn-hangzhou.aliyuncs.com/sky1.jpg',
status: 'uploading',
}, {
url: 'https://riceui.oss-cn-hangzhou.aliyuncs.com/sky1.jpg',
status: 'failed',
}, {
url: 'https://riceui.oss-cn-hangzhou.aliyuncs.com/sky1.jpg',
status: 'success',
}])
</script>读取前置处理
通过传入 beforeRead 函数可以在文件读取前进行校验和处理,返回 true 或 files 文件列表 表示校验通过,支持返回 Promise 对 文件进行自定义处理,例如压缩图片。
vue
<template>
<rice-uploader :before-read="onBeforeRead4" :action="action" />
</template>
<script setup lang="ts">
import { UploaderFileItem} from "@/uni_modules/rice-ui"
const action = ref('https://api.riceui.cn/app/upload')
const onBeforeRead4 = (files : UploaderFileItem[]) => {
//过滤大于200kb的文件
return files.filter(v => (v.size!) <= 200 * 1024)
}
</script>上传前置处理
通过传入 beforeUpload 函数可以在文件上传前进行校验和处理,返回 false 可终止文件上传,支持返回Promise,Promise 对象 resolve(false) 或 reject 时终止文件上传。
vue
<template>
<rice-uploader :before-upload="onBeforeUpload5" :action="action" :success-code="200" @complete="onComolete" />
</template>
<script setup lang="ts">
import { UploaderFileItem} from "@/uni_modules/rice-ui"
const action = ref('https://api.riceui.cn/app/upload')
//获取文件后缀名
const getFileExtension = (url : string) => {
const lastDotIndex = url.lastIndexOf('.')
if (lastDotIndex == -1 || lastDotIndex == url.length - 1) return ''
return url.slice(lastDotIndex + 1)
}
//上传前置处理--获取阿里云oss参数直传 示例
const onBeforeUpload5 = async (file : UploaderFileItem) => {
//获取阿里云oss参数直传
return new Promise<boolean>((resolve) => {
file.status = 'uploading'
uni.request({
url: 'https://api.riceui.cn/app/getOssSign',
method: 'POST',
success: res => {
const result = res.data as UTSJSONObject
const data = result['data'] as UTSJSONObject
// 会和prop中的 formData合并
file.formData = data
//获取文件后缀名
// #ifdef WEB
const extension = getFileExtension(file.fileName ?? file.url)
// #endif
// #ifndef WEB
const extension = getFileExtension(file.url)
// #endif
file.formData['key'] = new Date().getTime() + `.${extension}`
//会覆盖prop中的action
file.action = data.getString('host')
resolve(true)
},
fail: err => {
console.log('err', err)
file.status = 'failed'
resolve(false)
}
})
})
}
</script>上传完成前置处理
- 通过传入
onSuccess函数可以在文件上传完成后进行处理,如根据后端的返回数据判断此次上传是否真的成功了;替换url的链接为上传成功后的网络链接等,返回false表示上传失败。 - 通过传入
onFail函数可以在文件上传失败后进行处理
vue
<template>
<rice-uploader :on-success="onSuccess6" :on-fail="onFail6" :action="action" />
</template>
<script setup lang="ts">
import { UploaderFileItem,UploaderSuccess, UploaderFail} from "@/uni_modules/rice-ui"
const action = ref('https://api.riceui.cn/app/upload')
const onSuccess6 = (response : UploaderSuccess, file : UploaderFileItem) => {
const result = JSON.parse<UTSJSONObject>(response.data) ?? {}
//自定义上传失败,请根据后端接口的实际情况进行处理
if (response.statusCode != 200 || result['code'] != 0) {
file.status = 'failed'
return false
}
//上传成功,替换url链接为上传成功后的网络图片链接,请根据上传成功后的实际情况进行处理
const data = (result['data']) as UTSJSONObject
file.url = data.getString('url') ?? file.url
return true
}
//上传失败
const onFail6 = (response : UploaderFail, file : UploaderFileItem) => {
console.log('onFail6', response)
file.message = `fail[${response.statusCode}]`
}
</script>删除前置处置
通过传入 beforeRemove 函数可以在文件删除之前进行处置,返回 false 可停止删除,支持返回Promise,Promise 对象 resolve(false) 或 reject 时停止删除
vue
<template>
<rice-uploader v-model="(fileList7 as UploaderFileItem[])" :before-remove="beforeRemove7" :action="action" @remove="onRemove" />
</template>
<script setup lang="ts">
import { UploaderFileItem,UploaderSuccess, UploaderFail} from "@/uni_modules/rice-ui"
const action = ref('https://api.riceui.cn/app/upload')
const fileList7 = ref<UploaderFileItem[]>([{
url: 'https://riceui.oss-cn-hangzhou.aliyuncs.com/sky1.jpg',
fileName: '图一', //可选
uid: '1', //可选,不传时随机生成
}, {
url: 'https://riceui.oss-cn-hangzhou.aliyuncs.com/flower2.jpg',
fileName: '图二', //可选
uid: '2', //可选,不传时随机生成
}, {
url: 'https://riceui.oss-cn-hangzhou.aliyuncs.com/sky1.jpg',
fileName: '图三', //可选
}])
const beforeRemove7 = (file : UploaderFileItem, index : number) => {
return new Promise((resolve) => {
uni.showModal({
title: '删除提示',
content: `确认要删除${file.fileName ?? ''},uid:${file.uid}图片吗?`,
success: res => {
if (res.confirm) resolve(true)
}
})
})
}
//删除事件
const onRemove = (file : UploaderFileItem, index : number) => {
nextTick(() => {
showToast(`删除了:${file.fileName ?? file.uid};索引:${index}`)
})
}
</script>
- 通过
upload-text可以设置上传区域的提示语 - 通过
loading-text可以设置上传中的提示语 - 通过
upload-fail-text可以设置上传失败时的提示语
html
<rice-uploader upload-text="请选择图片" loading-text="传输中…" upload-fail-text="fail"/>自定义插槽
自定义上传区域的内容
vue
<template>
<rice-uploader accept="media" :action="action" :max-count="2">
<template #default>
<button type="primary" size="mini">上传图片</button>
</template>
</rice-uploader>
</template>手动上传
设置 auto-upload 为 false 后,可以手动控制上传的时机
vue
<template>
<rice-uploader :auto-upload="false" ref="uploader8Ref" :action="action" :success-code="200" :max-count="99"
@complete="onComplete8" />
<rice-button type="primary" text="开始上传" style="width: 100px;" size="small" @click="startUpload"></rice-button>
</template>
<script setup>
import { UploaderFileItem, UploaderComplete, UploaderSuccess, UploaderFail } from "@/uni_modules/rice-ui"
const uploader8Ref = ref<RiceUploaderComponentPublicInstance | null>(null)
const startUpload = () => {
uploader8Ref.value!.upload()
}
const onComplete8 = (fileList : UploaderFileItem[], result : UploaderComplete) => {
console.log('手动上传完成了:', fileList)
const successCount = result.successList.length
const failCount = result.failList.length
showToast(`上传成功${successCount}张,上传失败${failCount}张`)
}
</script>自定义实现上传逻辑
设置 auto-upload 为 false 后,可以自定义实现上传逻辑
vue
<template>
<rice-uploader v-model="(fileList9 as UploaderFileItem[])" :auto-upload="false" />
<rice-button type="primary" text="开始上传" style="width: 100px;" size="small" @click="startUploadFn"></rice-button>
</template>
<script setup>
const fileList9 = ref<UploaderFileItem[]>([])
const startUploadFn = () => {
//选出状态为 ready 的文件进行上传
const readyFiles = fileList9.value.filter(file => file.status == 'ready')
if (readyFiles.length <= 0) {
showToast('无待上传的图片')
return
}
readyFiles.map(file => {
file.status = 'uploading'
const task = uni.uploadFile({
url: action.value,
filePath: file.url,
formData: { username: 'zhangsan' },
name: file.uid,
success: res => {
if (res.statusCode == 200) {
file.status = 'success'
} else {
file.status = 'failed'
file.message = '上传失败'
}
},
fail: err => {
console.log('上传失败', err)
file.status = 'failed'
file.message = '上传失败'
}
})
//上传进度
task.onProgressUpdate(res => {
file.message = res.progress + '%'
})
})
}
</script>监听Add事件执行上传
设置 auto-upload 为 false 后,可以监听Add事件执行上传逻辑
vue
<template>
<rice-uploader :auto-upload="false" @add="onAdd10" />
</template>
<script setup>
const onAdd10 = (files : UploaderFileItem[]) => {
files.map(file => {
file.status = 'uploading'
const task = uni.uploadFile({
url: action.value,
filePath: file.url,
formData: { username: 'zhangsan' },
name: file.uid,
success: res => {
if (res.statusCode == 200) {
file.status = 'success'
} else {
file.status = 'failed'
file.message = '上传失败'
}
},
fail: err => {
console.log('上传失败', err)
file.status = 'failed'
file.message = '上传失败'
}
})
//上传进度
task.onProgressUpdate(res => {
file.message = res.progress + '%'
})
})
}
</script>注意
选择的文件全部上传完成后(不论是成功还是失败,自定义实现上传逻辑除外),都会触发complete事件,可以在该事件的第二个参数中拿到此次上传成功/失败的文件合集。
API
Props
| 属性名 | 类型 | 说明 | 默认值 |
|---|
| 属性名 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| v-model / model-value | UploaderFileItem[] | 上传的文件列表 | - |
| action | String | 上传地址 | - |
| accept | String | 上传文件的类型,可选值:media、image、video | image |
| auto-upload | Boolean | 是否自动上传,值为false时,可手动上传文件,默认true | - |
| name | String | 文件对应的 key , 开发者在服务器端通过这个 key 可以获取到文件二进制内容 | - |
| header | UTSJSONObject | HTTP 请求 Header, header 中不能设置 Referer | - |
| form-data | UTSJSONObject | HTTP 请求中其他额外的 form data | - |
| timeout | String | 超时时间,单位 ms,120000 | - |
| max-count | Number | 最大可上传数量 | 9 |
| max-duration | Number | 拍摄视频最长拍摄时间,单位秒。最长支持 60 秒,mode为 video时有效 | 60 |
| show-file-list | Boolean | 是否显示已上传文件列表 | true |
| preview | Boolean | 点击图片时是否开启图片预览,点击其他文件类型时(如video),预览功能需自行实现 | true |
| image-mode | String | 图片裁剪、缩放的模式,等同于官方image组件的mode,默认 scaleToFill | - |
| object-fit | String | 当视频大小与 video 容器大小不一致时,视频的表现形式。,等同于官方video组件的objectFit,默认 contain | - |
| upload-icon | String | 上传区域的icon | - |
| upload-icon-style | UTSJSONObject | 上传区域Icon 的style | - |
| upload-text | String | 上传区域的提示文字 | - |
| loading-text | String | 上传时的提示文字,默认 | 上传中… |
| upload-fail-text | String | 上传失败时的提示文字 | 上传失败 |
| show-percent | Boolean | 上传时是否显示进度,如80%,会覆盖loadingText设置的文字,默认false | - |
| show-success | Boolean | 上传成功后是否显示成功的icon | true |
| deletable | Boolean | 是否显示删除按钮,正在上传时恒不显示 | true |
| delete-icon | String | 删除图标的name值 | - |
| delete-style | UTSJSONObject | 删除图标的style | - |
| width | String|Number | 上传区域的宽度,默认80px | - |
| height | String|Number | 上传区域的高度,默认80px | - |
| bg-color | String | 上传区域的背景颜色 | - |
| disabled | Boolean | 是否禁用 | - |
| readonly | Boolean | 是否只读 | - |
| camera | String | 摄像切换,可选值:front、back | - |
| page-orientation | String | 屏幕方向。,可选值:auto、portrait、landscape | auto |
| size-type | string[] | original 原图,compressed 压缩图,默认二者都有 | - |
| source-type | string[] | album 从相册选图,camera 使用相机,默认二者都有 | - |
| extension | string[] | 根据文件拓展名过滤,每一项都不能是空字符串。默认不过滤。仅H5支持 | - |
| crop | ChooseImageCropOptions | 图像裁剪参数,设置后 sizeType 失效。见官方文档 | - |
| success-code | Number | 文件上传成功时,开发者服务器返回的 HTTP 状态码 | - |
| before-read | (files : UploaderFileItem[]) => Promise<any> | any | 文件读取前的回调函数,可以对文件进行过滤或压缩,返回值为 false 时会过滤该文件。支持返回一个 Promise 对象,Promise 对象 resolve(false) 或 reject 时过滤 | - |
| after-read | (files : UploaderFileItem[]) => void | 文件读取完成后的回调函数 | - |
| before-upload | (files : UploaderFileItem) => Promise<any> | any | 文件上传前的回调函数,返回 false 可终止文件上传,支持返回Promise,Promise 对象 resolve(false) 或 reject 时终止文件上传 | - |
| before-remove | (file : UploaderFileItem, index : number) => Promise<boolean|null> | boolean|null | 文件删除之前的回调函数,返回 false 可停止删除,支持返回Promise,Promise 对象 resolve(false) 或 reject 时停止删除 | - |
| on-success | (response : UploaderSuccess, file : UploaderFileItem) => boolean | null | 文件上传成功时的函数,可以在此函数中判断文件是否真的上传成功或替换url为上传成功后的网络链接等,返回false表示文件上传失败 | - |
| on-fail | (response : UploaderFail, file : UploaderFileItem) => void | 文件上传失败时的函数 | - |
| custom-style | Object | 自定义style | - |
方法
通过 ref 可以获取到 Uploader 实例并且调用实例的方法
| 方法名 | 说明 | 参数 | 返回值 |
|---|---|---|---|
| upload | 手动上传文件,只会上传 status 值为 ready 的文件 | - |
调用方法示例
ts
const uploaderRef = ref<RiceUploaderComponentPublicInstance | null>(null)
uploaderRef.value!.upload()Event 事件
| 事件名 | 说明 | 回调参数 |
|---|---|---|
| add | 文件选择完成后触发 | files: UploaderFileItem[] |
| remove | 文件删除完成后触发 | file: UploaderFileItem, index: number |
| complete | 文件全部上传完成后触发 | files: UploaderFileItem[], result: UploaderComplete[] |
| clickPrevide | 点击文件预览时触发,非图片格式的文件需自行实现预览功能 | file: UploaderFileItem,files: UploaderFileItem[] |
| error | 选择文件错误时触发 | errMsg:string |
Slots 插槽
| 名称 | 说明 | 参数 |
|---|---|---|
| default | 默认上传区域 | - |
| delete | 删除图标区域 | - |
UploaderFileItem 数据结构
每个文件拥有的属性如下:
| 键名 | 说明 | 类型 |
|---|---|---|
| url | 文件地址,必传 | String |
| poster | 文件封面地址,会覆盖url的值 | String |
| fileName | 文件名称,非H5端为空字符串 | String |
| status | 上传状态,值为:ready、uploading 、success failed | String |
| fileType | 文件类型 | String |
| message | 上传中/上传失败时的提示语,会覆盖prop中loadingText/uploadFailText的值 | String |
| percent | 上传进度的百分百,会覆盖 message 的值,单prop的 showPercent 为 true 时才有效 | String |
| size | 文件大小,单位:B | Number |
| duration | 视频时长 | Number |
| deletable | 文件是否可以删除,会覆盖 prop 中deletable的值 | String |
| uid | 唯一值,不传时会默认生成 | String |
| name | 文件对应的 key , 开发者在服务器端通过这个 key 可以获取到文件二进制内容,会覆盖 prop 中name的值 | String |
| action | 文件上传地址,会覆盖 prop 中action的值 | String |
| formData | HTTP 请求中其他额外的 form data,会和prop中的 formData 合并 | UTSJSONObject |
| header | HTTP 请求 Header, header 中不能设置 Referer,会和prop中的 header 合并 | UTSJSONObject |
类型定义
组件导出如下类型
ts
// 上传文件类型
type UploaderAccept = 'media' | 'image' | 'video'
// 上传状态
type UploaderStatus = 'ready' | 'uploading' | 'success' | 'failed'
//文件上传成功的数据
type UploaderSuccess = {
statusCode : number, //开发者服务器返回的 HTTP 状态码
data : string, //开发者服务器返回的数据
file : UploaderFileItem,
}
//文件上传失败的数据
type UploaderFail = {
errCode : number, //错误码(未统一,勿依赖)
statusCode : number, //开发者服务器返回的 HTTP 状态码
data : any | null, //开发者服务器返回的数据
errMsg : string, // 错误信息
file : UploaderFileItem,
}
//文件上传完成的数据
type UploaderComplete = {
successList : UploaderSuccess[], //上传成功合集
failList : UploaderFail[] //上传失败合集
}
// file 文件
type UploaderFileItem = {
url : string,
poster ?: string,
fileName ?: string,
status ?: 'ready' | 'uploading' | 'success' | 'failed',
fileType ?: string,
message ?: string,
percent ?: number,
size ?: number,
duration ?: number,
deletable ?: boolean,
uid ?: string,
name ?: string,
action ?: string,
formData ?: UTSJSONObject,
header ?: UTSJSONObject,
}ts
//组件类型
const textAreaRef=ref<RiceUploaderComponentPublicInstance|null>(null)