Skip to content

Uploader 上传器 1.0.18

手机扫码预览
23:37

组件名:rice-uploader

该组件用于上传图片、视频等文件场景。1.0.18 版本开始支持。

平台兼容性

uni-app x

AndroidiOS鸿蒙Next微信小程序h5

基础用法

  • 文件上传完毕后会触发 complete 事件,可以拿到上传成功或者失败的文件信息。
  • 如果传入了 successCode,则上传完成后,仅当返回的 HTTP状态码 与之相等才表示上传成功,未传值时,则不通过状态码进行比较,需自行通过 onSuccess回调函数进行判断
  • 默认选择文件完成后会自动上传,如需手动上传,设置 auto-uploadfalse 即可。
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 函数可以在文件读取前进行校验和处理,返回 truefiles 文件列表 表示校验通过,支持返回 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 可终止文件上传,支持返回PromisePromise 对象 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 可停止删除,支持返回PromisePromise 对象 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-uploadfalse 后,可以手动控制上传的时机

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-uploadfalse 后,可以自定义实现上传逻辑

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-uploadfalse 后,可以监听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-valueUploaderFileItem[]上传的文件列表-
actionString上传地址-
acceptString上传文件的类型,可选值:media、image、videoimage
auto-uploadBoolean是否自动上传,值为false时,可手动上传文件,默认true-
nameString文件对应的 key , 开发者在服务器端通过这个 key 可以获取到文件二进制内容-
headerUTSJSONObjectHTTP 请求 Header, header 中不能设置 Referer-
form-dataUTSJSONObjectHTTP 请求中其他额外的 form data-
timeoutString超时时间,单位 ms,120000-
max-countNumber最大可上传数量9
max-durationNumber拍摄视频最长拍摄时间,单位秒。最长支持 60 秒,mode为 video时有效60
show-file-listBoolean是否显示已上传文件列表true
previewBoolean点击图片时是否开启图片预览,点击其他文件类型时(如video),预览功能需自行实现true
image-modeString图片裁剪、缩放的模式,等同于官方image组件的mode,默认 scaleToFill-
object-fitString当视频大小与 video 容器大小不一致时,视频的表现形式。,等同于官方video组件的objectFit,默认 contain-
upload-iconString上传区域的icon-
upload-icon-styleUTSJSONObject上传区域Icon 的style-
upload-textString上传区域的提示文字-
loading-textString上传时的提示文字,默认上传中…
upload-fail-textString上传失败时的提示文字上传失败
show-percentBoolean上传时是否显示进度,如80%,会覆盖loadingText设置的文字,默认false-
show-successBoolean上传成功后是否显示成功的icontrue
deletableBoolean是否显示删除按钮,正在上传时恒不显示true
delete-iconString删除图标的name值-
delete-styleUTSJSONObject删除图标的style-
widthString|Number上传区域的宽度,默认80px-
heightString|Number上传区域的高度,默认80px-
bg-colorString上传区域的背景颜色-
disabledBoolean是否禁用-
readonlyBoolean是否只读-
cameraString摄像切换,可选值:front、back-
page-orientationString屏幕方向。,可选值:auto、portrait、landscapeauto
size-typestring[]original 原图,compressed 压缩图,默认二者都有-
source-typestring[]album 从相册选图,camera 使用相机,默认二者都有-
extensionstring[]根据文件拓展名过滤,每一项都不能是空字符串。默认不过滤。仅H5支持-
cropChooseImageCropOptions图像裁剪参数,设置后 sizeType 失效。见官方文档-
success-codeNumber文件上传成功时,开发者服务器返回的 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-styleObject自定义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上传状态,值为:readyuploadingsuccess failedString
fileType文件类型String
message上传中/上传失败时的提示语,会覆盖prop中loadingText/uploadFailText的值String
percent上传进度的百分百,会覆盖 message 的值,单prop的 showPercenttrue 时才有效String
size文件大小,单位:BNumber
duration视频时长Number
deletable文件是否可以删除,会覆盖 prop 中deletable的值String
uid唯一值,不传时会默认生成String
name文件对应的 key , 开发者在服务器端通过这个 key 可以获取到文件二进制内容,会覆盖 prop 中name的值String
action文件上传地址,会覆盖 prop 中action的值String
formDataHTTP 请求中其他额外的 form data,会和prop中的 formData 合并UTSJSONObject
headerHTTP 请求 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)