Skip to content

Uploader 文件/图片上传

介绍

文件上传组件,用于让用户上传文件或者图片,支持多选、预览、删除等功能。

导入

js
import Uploader from '@/components/form/Uploader.vue'

用法

基础用法

vue
<template>
  <Uploader
    :upload="(action) => {
      //测试完成上传,实际这里需要调用地址上传
      action.onFinish({
        uploadedUrl: action.item.filePath,
      });
    }"
  />
</template>

<script setup lang="ts">
import Uploader from '@/components/form/Uploader.vue';
</script>

预览图片

Uploader 根据文件后缀来判断是否为图片文件。如果图片 URL 中不包含类型信息,可以添加 isImage 标记来声明。非图片文件将显示一个文件类型图标。

vue
<template>
  <Uploader
    :upload="(action) => {
      //测试完成上传,实际这里需要调用地址上传
      action.onFinish({
        uploadedUrl: action.item.filePath,
      });
    }"
    :intitalItems="[
      {
        filePath: '1.jpg',
        previewPath: 'https://imengyu.top/assets/images/test/1.jpg',
        state: 'success',
      },
      {
        filePath: '2.jpg',
        previewPath: 'https://imengyu.top/assets/images/test/2.jpg',
        state: 'success',
      },
      {
        filePath: '3.docx',
        state: 'success',
      },
      {
        filePath: '4.ppt',
        state: 'success',
      },
      {
        filePath: '5.mp4',
        state: 'success',
      },
      {
        filePath: '6.xls',
        state: 'success',
      },
    ]"
    :maxUploadCount="6"
  />
</template>

<script setup lang="ts">
import Uploader from '@/components/form/Uploader.vue';
</script>

上传状态

通过 status 属性可以标识上传状态,uploading 表示上传中,fail 表示上传失败,success 表示上传完成。

vue
<template>
  <Uploader
    :upload="uploadStateTest"
    :intitalItems="[
      {
        filePath: '1.jpg',
        previewPath: 'https://imengyu.top/assets/images/test/1.jpg',
        state: 'fail',
        message: '上传失败',
      },
      {
        filePath: '2.jpg',
        previewPath: 'https://imengyu.top/assets/images/test/2.jpg',
        state: 'uploading',
        message: '正在上传',
      },
      {
        filePath: '2.jpg',
        previewPath: 'https://imengyu.top/assets/images/test/2.jpg',
        state: 'success',
      },
    ]"
    :maxUploadCount="6"
  />
</template>

<script setup lang="ts">
import Uploader from '@/components/form/Uploader.vue';
import type { UploaderAction } from '@/components/form/Uploader';

function uploadStateTest(action: UploaderAction) {
  //开始上传,这里是测试,实际这里需要调用地址上传
  action.onStart();

  //测试上传返回进度
  let pec = 0;
  const timer = setInterval(() => {
    pec = Math.min(100, pec + Math.floor(Math.random() * 25));
    action.onProgress(pec);

    if (pec >= 100) {
      clearInterval(timer);

      if (Math.random() < 0.2) {
        //上传失败
        action.onError('测试失败');
      }
      else {
        //完成上传
        action.onFinish({
          uploadedUrl: action.item.filePath,
        });
      }
    }
  }, 500);
}
</script>

限制上传数量

通过 maxUploadCount 属性可以限制上传文件的数量,上传数量达到限制后,会自动隐藏上传区域。

vue
<template>
  <Uploader
    :upload="(action) => {
      //测试完成上传,实际这里需要调用地址上传
      action.onFinish({
        uploadedUrl: action.item.filePath,
      });
    }"
    :intitalItems="[
      {
        filePath: '1.jpg',
        previewPath: 'https://imengyu.top/assets/images/test/1.jpg',
        state: 'success',
      },
      {
        filePath: '2.jpg',
        previewPath: 'https://imengyu.top/assets/images/test/2.jpg',
        state: 'success',
      },
    ]"
    :maxUploadCount="3"
  />
</template>

<script setup lang="ts">
import Uploader from '@/components/form/Uploader.vue';
</script>

限制上传大小

通过 maxFileSize 属性可以限制上传文件的大小,超过大小的文件会被自动过滤,这些文件信息可以通过 onOverSize 事件获取。注意,使用自定义选择器时必须获取文件大小才能正确判断。

vue
<template>
  <Uploader
    :upload="(action) => {
      //测试完成上传,实际这里需要调用地址上传
      action.onFinish({
        uploadedUrl: action.item.filePath,
      });
    }"
    :maxUploadCount="6"
    :maxFileSize="1024"
    @overSize="(item) => {
      dialog?.alert({
        title: 'onOverSize',
        content: `文件${item.filePath}超出大小`,
      });
    }"
  />
</template>

<script setup lang="ts">
import Uploader from '@/components/form/Uploader.vue';
import DialogRoot, { type DialogAlertRoot } from '@/components/dialog/DialogRoot.vue';
import { ref } from 'vue';

const dialog = ref<DialogAlertRoot>();
</script>

列表模式

设置通过 listType='list' 属性可以将上传区域切换为列表模式。

vue
<template>
  <Uploader
    listType="list"
    
    :upload="(action) => {
      //测试完成上传,实际这里需要调用地址上传
      action.onFinish({
        uploadedUrl: action.item.filePath,
      });
    }"
    :intitalItems="[
      {
        filePath: '1.jpg',
        previewPath: 'https://imengyu.top/assets/images/test/1.jpg',
        state: 'success',
      },
      {
        filePath: '2.jpg',
        message: '上传失败',
        state: 'fail',
      },
      {
        filePath: '5.mp4',
        state: 'uploading',
        progress: 50,
      },
      {
        filePath: '3.docx',
        state: 'success',
      },
      {
        filePath: '4.ppt',
        state: 'success',
      },
      {
        filePath: '6.xls',
        state: 'success',
      },
    ]"
    :maxUploadCount="10"
  />
</template>

<script setup lang="ts">
import Uploader from '@/components/form/Uploader.vue';
</script>

自定义上传样式

可以自定义渲染整个上传区域的样式。通常可以用在单独上传例如头像上传。

vue
<template>
  <Uploader
    :upload="(action) => {
      //测试完成上传,实际这里需要调用地址上传
      action.onFinish({
        uploadedUrl: action.item.filePath,
      });
    }"
    :maxUploadCount="1"
  >
    <template #uploader="{ onClick, items }">
      <Avatar
        :size="120"
        :url="items[0]?.filePath || ''"
        defaultAvatar="https://imengyu.top/assets/images/test/icon.png"
        @click="onClick"
      />
    </template>
  </Uploader>
</template>

<script setup lang="ts">
import Uploader from '@/components/form/Uploader.vue';
import Avatar from '@/components/display/Avatar.vue';
</script>

API 参考

Uploader

文件上传组件。

Props

名称说明类型必填默认值
maxUploadCount最大上传数number1
maxFileSize最大上传文件的大小(B),为 0 则不限制number0
disabled是否禁用文件上传booleanfalse
showUpload是否显示文件已上传列表booleantrue
showDelete是否在已上传列表条目中显示删除按钮booleantrue
listType上传列表的显示模式,可选值为 'grid' 或 'list''list' | 'grid''grid'
uploadWhenAdded是否在用户添加图片后自动进行上传booleantrue
uploadQueueMode上传队列模式,可选值为 'all' 或 'sequential''all' | 'sequential''all'
itemDefaultSource条目的默认图片stringundefined
itemSize条目的大小{ width: number, height: number }{ width: 750 / 4 - 15, height: 750 / 4 - 15 }
itemListStyle列表自定义外层样式ViewStyleundefined
itemStyle条目的自定义外层样式ViewStyleundefined
itemImageStyle条目的自定义图片样式ViewStyleundefined
itemMaskTextStyle条目的自定义信息遮罩样式TextStyleundefined
itemMaskStyle条目的自定义信息容器样式ViewStyleundefined
intitalItems初始列表中的条目UploaderItem[][]
chooseType选择文件类型,可选值为 'image'、'video' 或 'file''image' | 'video' | 'file''image'
upload上传处理函数,不提供则无法上传(item: UploaderAction) => voidundefined
onPickImage自定义选择文件组件() => Promise<UploaderItem[]>undefined
onBeforeAdd上传前校验和处理函数(item: UploaderItem) => Promise<UploaderItem | undefined>undefined
onRetryClick自定义上传失败文件点击的事件(item: UploaderItem) => voidundefined
onPreviewClick自定义已上传文件点击的事件(item: UploaderItem) => voidundefined
onDeleteClick自定义已上传文件点击删除按钮的事件(item: UploaderItem) => Promise<void>undefined
onOverSize当上传文件超过大小时触发(item: UploaderItem) => voidundefined
onOverCount当上传文件超过数量时触发(count: number, max: number) => voidundefined

Slots

名称说明
uploader自定义整个上传区域的渲染
uploadItem自定义上传项的渲染
addButton自定义添加按钮的渲染

Events

名称说明参数
updateList上传列表更新时触发UploaderItem[]

主题变量

名称类型默认值说明
UploaderItemSizeobject{ width: 750 / 4 - 15, height: 750 / 4 - 15 }上传项的默认大小