Skip to content
On this page

ImageUploader 图片上传

注:

  • 类似于微信朋友圈上传图片的组件。
  • 支持表单,具体可参考 Form
vue
<template>
  <ta-group title="基础用法">
    <ta-image-uploader
      :uploadReady="hookUploadOrFail"
      @change="onChange"
      @delete="onDelete"
      :accept="['png', 'jpg']"
      :maxCount="9"
      v-model="imageList"
      multiple
    />
  </ta-group>
  <ta-group title="上传前置处理">
    <ta-image-uploader
      :beforeUpload="hookBeforeUpload"
      :uploadReady="hookUpload"
      :accept="['png', 'jpg']"
      :maxCount="9"
      v-model="imageList3"
      multiple
    />
  </ta-group>
  <ta-group title="禁用删除">
    <ta-image-uploader v-model="imageList2" :deletable="false" :uploadReady="hookUpload" />
  </ta-group>
  <ta-group title="禁用上传">
    <ta-image-uploader disabled />
  </ta-group>
</template>

<script lang="ts">
import { defineComponent, reactive } from 'vue'
import {
  type ImageUploaderBeforeUpload,
  type ImageUploaderOnDelete,
  type ImageUploaderUploadReady,
  showToast
} from '@/index'

export default defineComponent({
  name: 'ExpImageUploader',
  setup() {
    const imageList = reactive<string[]>([])
    const imageList2 = reactive<string[]>([
      'https://cdn.fox2.cn/vfox/empty/default@2x.png',
      'https://cdn.fox2.cn/vfox/empty/error@2x.png'
    ])
    const imageList3 = reactive<string[]>([])

    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 {
      imageList,
      imageList2,
      imageList3,

      hookBeforeUpload,
      hookUploadOrFail,
      hookUpload,
      onChange,
      onDelete
    }
  }
})
</script>

Import

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

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

Import Type

组件导出的类型定义:

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

Props

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

ImageUploaderBeforeUpload

ts
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
vue
<template>
  <ta-image-uploader :beforeUpload="onBeforeUpload" />
</template>

<script>
export default {
  methods: {
    onBeforeUpload(file, { formatSize }) {
      if (file.size > 1024 * 1024) {
        Toast.showToast(`上传图片不能大于 ${formatSize(1024 * 1024)}`)
        return false
      }
      Toast.showToast(`上传图片大小为 ${formatSize(file.size)}`)
    }
  }
}
</script>

ImageUploaderUploadReady

ts
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 提供的改变状态方法是不可逆的。

vue
<template>
  <ta-image-uploader :uploadReady="onUpload" />
</template>

<script>
export default {
  methods: {
    onUpload(file, handlers) {
      handlers.setUploading('上传中...')

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

Events

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

delete 的回调参数

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