Skip to content

File Upload 文件上传

选择或拖入本地文件,支持类型、大小、数量校验及后端文件回显。组件不发起 HTTP 请求。

命令行安装

bash
npx @loongship-kit/ui add file-upload

基础用法

使用 v-model:file-list 获取文件列表。默认是单文件模式,再次选择会替换原文件。

已选择:暂无文件
查看代码
vue
<script setup lang="ts">
import { ref } from 'vue'
import { FileUpload } from '@/components/loongship/file-upload'
import type { FileUploadItem } from '@/components/loongship/file-upload'

const files = ref<FileUploadItem[]>([])
</script>

<template>
  <div>
    <FileUpload v-model:file-list="files" />
    <span>已选择:{{ files[0]?.name || '暂无文件' }}</span>
  </div>
</template>

拖拽上传

设置 drag 后切换为拖拽投放区,同时仍可点击打开文件选择器。

查看代码
vue
<script setup lang="ts">
import { ref } from 'vue'
import { FileUpload } from '@/components/loongship/file-upload'
import type { FileUploadItem } from '@/components/loongship/file-upload'

const files = ref<FileUploadItem[]>([])
</script>

<template>
  <FileUpload v-model:file-list="files" drag />
</template>

多文件与文件限制

multiple 模式会把新文件追加到现有列表,并以文件名、大小和最后修改时间去重。下面的示例最多接收 3 个 PDF 或图片文件,且每个文件不超过 5 MB。

已接收 0 个,最近拒绝 0 个。
查看代码
vue
<script setup lang="ts">
import { ref } from 'vue'
import { FileUpload } from '@/components/loongship/file-upload'
import type { FileUploadItem, FileUploadRejection } from '@/components/loongship/file-upload'

const attachments = ref<FileUploadItem[]>([])
const lastRejections = ref<FileUploadRejection[]>([])
</script>

<template>
  <div>
    <FileUpload
      v-model:file-list="attachments"
      multiple
      accept=".pdf,image/*"
      :max-size="5 * 1024 * 1024"
      :max-files="3"
      @reject="lastRejections = $event"
    />
    <span>已接收 {{ attachments.length }} 个,最近拒绝 {{ lastRejections.length }} 个。</span>
  </div>
</template>

文件接收规则

accept 支持逗号分隔的扩展名、精确 MIME 和 MIME 通配符,例如 .pdf,application/json,image/*。浏览器选择器会使用同一规则作为提示,组件仍会在接收文件时再次校验。

自定义内容

triggerfileerror 插槽分别自定义触发器、文件项和错误内容。

vue
<template>
  <FileUpload v-model:file-list="files" multiple>
    <template #trigger="{ disabled }">
      <span :aria-disabled="disabled">添加附件</span>
    </template>

    <template #file="{ file, remove }">
      <span>{{ file.name }}</span>
      <button type="button" @click="remove">删除</button>
    </template>

    <template #error="{ rejections }">
      <span>{{ rejections.map(item => item.message).join(';') }}</span>
    </template>
  </FileUpload>

  <FileUpload v-model:file-list="files" drag>
    <template #trigger="{ dragging }">
      <span>{{ dragging ? '松开以添加文件' : '把附件拖到这里' }}</span>
    </template>
  </FileUpload>
</template>

上传文件

监听 select,或从 fileList 中筛选带有 raw 的本地文件后自行上传:

ts
const formData = new FormData()

for (const item of files.value) {
  if (item.raw) formData.append('files', item.raw)
}

不要依赖原生表单上传

组件在处理每次原生选择后会清空内部 input,使再次选择同一文件仍能触发事件。请使用文件项的 raw 自行上传,不要依赖原生表单的 multipart/form-data 提交。

后端回显

后端文件提供文件名和 URL 即可;有稳定标识时可传入 uid

ts
const files = ref<FileUploadItem[]>([
  {
    name: '航次报告.pdf',
    size: 102400,
    type: 'application/pdf',
    url: '/api/files/1001'
  }
])

后端项通常具有 url 而没有 raw;本地新增项具有 raw,并由组件自动生成 uid。删除、排序和展示都通过同一个 fileList 完成。

API

属性

属性类型默认值说明
v-model:file-listFileUploadItem[]-受控文件项列表
defaultFileListFileUploadItem[]-非受控模式初始文件项
multiplebooleanfalse是否允许多个文件
dragbooleanfalse是否启用拖拽投放区
acceptstring-扩展名或 MIME 接收规则
maxSizenumber-单文件最大字节数
maxFilesnumber-多文件模式最大数量
disabledbooleanfalse禁止选择、拖入和删除
promptstring'拖拽文件到此处,或'默认投放区提示
browseLabelstring'选择文件'选择文本及原生 input 可访问名
removeLabelstring'移除文件'删除按钮可访问名
classClassValue-根元素自定义类名

事件

事件参数说明
update:fileListfiles: FileUploadItem[]文件项列表改变
selectfiles: FileUploadItem[]本次成功接收的新增文件项
rejectrejections: FileUploadRejection[]本次拒绝的全部文件及原因
removefile: File, index: number文件被移除

拒绝原因

拒绝码为 typesizecountduplicate。一次操作可以同时接收有效文件并拒绝无效文件。

FileUploadItem

字段类型说明
uidstring可选列表标识;本地项由组件自动生成
namestring文件名
sizenumber可选文件大小,单位字节
typestring可选 MIME 类型
urlstring可选预览或下载地址,通常用于后端回显
rawFile可选原生文件,仅本地新增项具有

插槽

插槽参数说明
triggerdragging, disabled, files两种模式共用的文件选择触发器
filefile, index, remove()单个文件项
errorrejections最近拒绝提示内容