SwUploadFile

SwUploadFile is a chunked upload component for plain files (PDF / documents / zip — anything that isn't an image or video), supporting both click-to-select and drag-and-drop. It is the unstyled UI shell over the useUploader().uploadFile capability: it reuses the same chunked endpoint as SwUploadVideo, but without the transcoding step (no queryFn needed) — the chunk-success response already carries an accessible URL, so uploadFn resolves the result directly.

Use SwUploadImage for images, SwUploadVideo for videos, and this component for everything else. All three are unstyled: they render no UI of their own, inject upload logic via uploadFn, and expose state through the default slot.

Basic Usage + Progress

Click to select a file; the progress scope variable and progress event reflect chunked upload progress in real time.

Basic (click upload + progress)

加载中...
<script setup lang="ts">
const uploader = useUploader()

function onDone(result: { id: string; value: string }) {
  form.attachment = { id: result.id, url: result.value }
}
</script>

<template>
  <SwUploadFile :upload-fn="uploader.uploadFile" @success="onDone" v-slot="{ open, pending, progress }">
    <SwButton :disabled="pending" @click="open">
      {{ pending ? `Uploading ${progress}%` : 'Select File' }}
    </SwButton>
  </SwUploadFile>
</template>

Custom trigger area (#default slot)

The "+ upload card": the default slot fully takes over the trigger UI; a clickable download link appears when done.

+ upload card (slot customization + download link)

加载中...

Drag and Drop

Use the slot's isOver to highlight the drop zone. Plain files are not mime-restricted — any file can be dropped.

Drag + click dual channel

加载中...

Restrict file types (accept)

accept is passed through to the file picker, filtering at the selection level.

PDF / zip only

加载中...

Multiple Files

Enable multiple to select or drop several files at once; they upload concurrently and emit success one by one.

Multiple files

加载中...

Progress trade-off: progress is accurate for single-file uploads; with multiple, per-file progress interleaves (last writer wins), so the progress bar is primarily meaningful for the single-file case.

Props

NameTypeRequiredDefaultDescription
uploadFn(file: File, options?: FileUploadOptions) => Promise<FileUploadResult>✓—Actual upload function, usually useUploader().uploadFile
acceptstring'*'File picker accept (plain files unrestricted by default)
chunkSizenumber2097152 (2 MB)Chunk size in bytes, forwarded to uploadFn
retriesnumber3Max retries per chunk, forwarded to uploadFn
concurrencynumberundefinedConcurrent chunks; defaults to 6 underneath, forwarded to uploadFn
multiplebooleanfalseWhether to allow multiple files

Type Definitions

FileUploadOptions

interface FileUploadOptions {
  chunkSize?: number
  retries?: number
  concurrency?: number
  onProcess?: (result: ChunkProgress) => void
  onBefore?: (file: File) => void
}

FileUploadResult

type FileUploadResult = {
  id: string // Backend file ID (business-side foreign key)
  value: string // File access URL (same `value` semantics as uploadImage)
  file_md5: string // Whole-file MD5
}

Events

EventPayloadDescription
progresspct: numberUpload progress percentage (0–100)
successFileUploadResultFires when a single file uploads successfully (one per file)
errorerr: ErrorFires on upload error (non-Error normalized to Error)

Slots

default (scoped slot)

Scope variableTypeDescription
isOverbooleanA file is hovering over the zone
pendingbooleanUpload in progress
progressnumberCurrent upload progress (0–100)
open() => voidManually open the file dialog

Notes

  • Unstyled: no built-in CSS; the UI is entirely up to the slot consumer.
  • uploadFn is usually wrapped from useUploader (the uploadFile method); demos use a mock to illustrate the flow.
  • No transcoding step: the key difference from SwUploadVideo — plain files yield value (URL) immediately after upload, with no queryFn polling.
  • Repeated triggers during pending are ignored (prevents duplicate uploads); the UI should reflect pending with a disabled / loading state.