ImageUploader 图片上传

注:

  • 类似于微信朋友圈上传图片的组件。
  • 支持表单,具体可参考 Form
import {
  TaImageUploader,
  TaGroup,
  ImageUploaderBeforeUpload,
  ImageUploaderOnDelete,
  ImageUploaderUploadReady,
  showToast
} from '@/index'

const imageList2 = [
  'https://cdn.fox2.cn/vfox/empty/default@2x.png',
  'https://cdn.fox2.cn/vfox/empty/error@2x.png'
]

export default function ExpImageUploader() {
  const hookBeforeUpload: ImageUploaderBeforeUpload = (
    file,
    { formatSize }
  ) => {
    if (file.size > 1024 * 1024) {
      showToast(`上传图片不能大于 ${formatSize(1024 * 1024)}`)
      return false
    }
    showToast(`上传图片大小为 ${formatSize(file.size)}`)
  }

  const hookUploadOrFail: ImageUploaderUploadReady = (file, handlers) => {
    handlers.setUploading('上传中...')

    setTimeout(() => {
      getDataUrl(file).then(url => {
        if (Math.random() > 0.5) {
          handlers.fail('模拟失败')
        } else {
          handlers.success(url)
        }
      })
    }, 2000)
  }

  function getDataUrl(file: File) {
    return new Promise<string>(resolve => {
      const fr = new FileReader()
      fr.onload = function (e) {
        resolve((e.target?.result as string) ?? '')
      }
      fr.readAsDataURL(file)
    })
  }

  const hookUpload: ImageUploaderUploadReady = (file, handlers) => {
    getDataUrl(file).then(url => {
      handlers.success(url)
    })
  }

  const onChange = (res: string[]) => {
    console.log('change', res)
  }

  const onDelete: ImageUploaderOnDelete = res => {
    console.log('delete', res)
  }

  return (
    <>
      <TaGroup title="基础用法">
        <TaImageUploader
          uploadReady={hookUploadOrFail}
          onChange={onChange}
          onDelete={onDelete}
          accept={['png', 'jpg']}
          maxCount="9"
          multiple
        />
      </TaGroup>
      <TaGroup title="上传前置处理">
        <TaImageUploader
          beforeUpload={hookBeforeUpload}
          uploadReady={hookUpload}
          accept={['png', 'jpg']}
          maxCount="9"
          multiple
        />
      </TaGroup>
      <TaGroup title="禁用删除">
        <TaImageUploader
          value={imageList2}
          deletable={false}
          uploadReady={hookUpload}
        />
      </TaGroup>
      <TaGroup title="禁用上传">
        <TaImageUploader disabled />
      </TaGroup>
    </>
  )
}

Import

import { TaImageUploader } from 'tantalum-ui-mobile-react'

具体的引入方式可以参考引入组件

Import Type

组件导出的类型定义:

import type {
  ImageUploaderAccept,
  ImageUploaderBeforeUpload,
  ImageUploaderUploadReady,
  ImageUploaderOnDelete
} from 'tantalum-ui-mobile-react'

Props

属性类型默认值必填说明
valuestring[]已上传的图片 URL 列表
acceptImageUploaderAccept默认 'all', 可选 'jpg' 'jpeg' 'png' 'webp',支持多个数组
columnNumbernumber3渲染列数,同 Order 组件
maxCountnumber | string9文件上传数量限制,上传中/上传失败也会占一个坑位
previewbooleantrue是否在点击缩略图后展示全屏图片预览
disabledbooleanfalse是否禁用文件上传
multiplebooleanfalse是否开启图片多选,部分安卓机型不支持
deletablebooleantrue是否允许删除图片
imageModeImageMode'aspectFill'图片的填充模式,通 Image 组件的 mode 属性
beforeUploadImageUploaderBeforeUpload文件读取前的回调函数,返回 false 或 Promise<false> 可终止文件上传
uploadReadyImageUploaderUploadReady转入上传文件操作的回调函数

ImageUploaderBeforeUpload

type ImageUploaderBeforeUpload = (file: File, handlers: {
  formatSize(size: number): string
}) => boolean \| void \| Promise<boolean | File\>

上传前进行校验和处理,返回 falsePromise<false> 表示校验失败。也可以返回修改过的 File 对象,如果压缩图片等。

handlers 提供的方法

handlers 方法参数返回说明
handlers.formatSize(size: number) => string把图片的文件大小数值转为可读的,如 10MB, 10.5KB
const hookBeforeUpload: ImageUploaderBeforeUpload = (
    file,
    { formatSize }
  ) => {
    if (file.size > 1024 * 1024) {
      showToast(`上传图片不能大于 ${formatSize(1024 * 1024)}`)
      return false
    }
    showToast(`上传图片大小为 ${formatSize(file.size)}`)
  }

</script>

ImageUploaderUploadReady

type ImageUploaderUploadReady = (
  file: File,
  handlers: {
    getUploadId(): number
    formatSize(size: number): string
    setUploading(message: string): void
    fail(e?: string | Error): void
    success(url: string): void
  }
) => void

在该节点中将文件上传至服务器。

handlers 提供的方法

handlers 方法参数返回说明
handlers.getUploadId() => number获取图片上传分配的唯一值
handlers.formatSize(size: number) => string把图片的文件大小数值转为可读的,如 10MB, 10.5KB
handlers.setUploading(message: string) => void设置图片上传状态为上传中
handlers.success(url: string) => void设置图片上传状态为上传成功,传入接口返回的 URL
handlers.fail(e?: string | Error) => void设置图片上传状态为上传失败,传入错误信息

注:整个上传流程分为 3 个阶段:reading -> uploading -> uploaded | failed,handlers 提供的改变状态方法是不可逆的。

const hookUploadOrFail: ImageUploaderUploadReady = (file, handlers) => {
  handlers.setUploading('上传中...')

  setTimeout(() => {
    customGetFileUrl(file).then(url => {
      if (Math.random() > 0.5) {
        handlers.fail('模拟失败')
      } else {
        handlers.success(url)
      }
    })
  }, 2000)
}

Events

事件描述回调函数参数TypeScript 函数
onDelete图片被删除时触发payload: { index: number, item: { id: number, status: string, url: string } }ImageUploaderOnDelete
onChange已上传的图片 URL 列表改变时value: string[]

delete 的回调参数

类型说明
indexnumber图片索引
item.idnumber图片上传项分配的唯一值
item.statusstringreading(uploadReady 后),uploading,uploaded,failed
item.urlstring图片 URL 地址