Upload
File upload with drag-and-drop, progress tracking, image preview, and multiple list styles.
vue
<script setup lang="ts">
import { ref } from 'vue'
import { VxUpload } from 'veloxui'
import type { UploadFile } from 'veloxui'
const files = ref<UploadFile[]>([])
</script>
<template>
<VxUpload v-model="files" action="/api/upload" />
</template>Drag and Drop
Enable drag for a drop zone area. Users can drag files into the zone or click to browse.
Drop files here or click to browse
Supports JPG, PNG, GIF up to 10MB
vue
<script setup lang="ts">
import { ref } from 'vue'
import type { UploadFile } from 'veloxui'
const files = ref<UploadFile[]>([])
</script>
<template>
<VxUpload
v-model="files"
action="/api/upload"
drag
multiple
tip="Supports JPG, PNG, GIF up to 10MB"
/>
</template>Picture List
Set list-type="picture" to show thumbnails alongside file names.
vue
<script setup lang="ts">
import { ref } from 'vue'
import type { UploadFile } from 'veloxui'
const files = ref<UploadFile[]>([])
</script>
<template>
<VxUpload
v-model="files"
action="/api/upload"
list-type="picture"
multiple
accept="image/*"
/>
</template>Picture Card
Set list-type="picture-card" for a grid of image cards with hover actions (preview and delete).
vue
<script setup lang="ts">
import { ref } from 'vue'
import type { UploadFile } from 'veloxui'
const files = ref<UploadFile[]>([
{ uid: '1', name: 'photo.jpg', status: 'success', url: 'https://picsum.photos/200/200?1' },
{ uid: '2', name: 'avatar.png', status: 'success', url: 'https://picsum.photos/200/200?2' },
])
</script>
<template>
<VxUpload
v-model="files"
action="/api/upload"
list-type="picture-card"
multiple
accept="image/*"
:limit="6"
/>
</template>Multiple Files
Enable multiple to allow selecting several files at once.
vue
<script setup lang="ts">
import { ref } from 'vue'
import type { UploadFile } from 'veloxui'
const files = ref<UploadFile[]>([])
</script>
<template>
<VxUpload v-model="files" action="/api/upload" multiple />
</template>File Limit
Set limit to restrict the number of files. The exceed event fires when the user tries to add more.
Maximum 3 files
vue
<script setup lang="ts">
import { ref } from 'vue'
import type { UploadFile } from 'veloxui'
const files = ref<UploadFile[]>([])
function handleExceed(files: File[], limit: number) {
alert(`You can only upload ${limit} files.`)
}
</script>
<template>
<VxUpload
v-model="files"
action="/api/upload"
multiple
:limit="3"
@exceed="handleExceed"
tip="Maximum 3 files"
/>
</template>Max File Size
Set max-size (in KB) to reject oversized files. Rejected files show as errors with the size message.
Max 500KB per file
vue
<script setup lang="ts">
import { ref } from 'vue'
import type { UploadFile } from 'veloxui'
const files = ref<UploadFile[]>([])
</script>
<template>
<VxUpload
v-model="files"
action="/api/upload"
:max-size="500"
tip="Max 500KB per file"
/>
</template>Custom Request
Use custom-request to handle uploads yourself (e.g. with axios, S3 presigned URLs, etc.).
Using custom upload handler
vue
<script setup lang="ts">
import { ref } from 'vue'
import type { UploadFile, UploadRequestOptions } from 'veloxui'
const files = ref<UploadFile[]>([])
function customUpload(options: UploadRequestOptions) {
const formData = new FormData()
formData.append('file', options.file)
fetch('/api/upload', { method: 'POST', body: formData })
.then(res => res.json())
.then(data => options.onSuccess(data))
.catch(err => options.onError(err.message))
}
</script>
<template>
<VxUpload
v-model="files"
:custom-request="customUpload"
multiple
/>
</template>Pre-populated List
Pass existing files via v-model to show a pre-populated file list.
report.pdf239.3 KB
data.csv12.1 KB
vue
<script setup lang="ts">
import { ref } from 'vue'
import type { UploadFile } from 'veloxui'
const files = ref<UploadFile[]>([
{ uid: '1', name: 'report.pdf', size: 245000, status: 'success' },
{ uid: '2', name: 'data.csv', size: 12400, status: 'success' },
])
</script>
<template>
<VxUpload v-model="files" action="/api/upload" />
</template>Disabled
file.pdf120.1 KB
vue
<template>
<VxUpload v-model="files" disabled />
</template>Props
| Prop | Type | Default | Description |
|---|---|---|---|
modelValue | UploadFile[] | [] | File list (v-model) |
action | string | '' | Upload endpoint URL |
headers | Record<string, string> | — | Custom request headers |
data | Record<string, string> | — | Extra form data fields |
name | string | 'file' | Form field name for the file |
withCredentials | boolean | false | Send cookies with request |
accept | string | '' | Accepted file types (e.g. image/*, .pdf) |
multiple | boolean | false | Allow multiple file selection |
limit | number | 0 | Max number of files (0 = unlimited) |
maxSize | number | 0 | Max file size in KB (0 = unlimited) |
disabled | boolean | false | Disable upload |
drag | boolean | false | Enable drag-and-drop zone |
listType | 'text' | 'picture' | 'picture-card' | 'text' | File list display style |
showFileList | boolean | true | Show file list below trigger |
autoUpload | boolean | true | Upload immediately on select |
customRequest | (options: UploadRequestOptions) => void | — | Custom upload handler |
beforeUpload | (file: File) => boolean | Promise<boolean> | — | Hook before upload starts |
tip | string | '' | Help text below trigger |
Events
| Event | Type | Description |
|---|---|---|
update:modelValue | (files) | File list changed |
change | (file, files) | A file was added or its status changed |
remove | (file, files) | A file was removed |
success | (file, response) | Upload succeeded |
error | (file, error) | Upload failed |
progress | (file, percent) | Upload progress updated |
exceed | (files, limit) | File limit exceeded |
preview | (file) | File preview requested (click name or eye icon) |
Slots
| Slot | Description |
|---|---|
default | Custom trigger content (replaces the button or drag zone inner) |
tip | Custom tip content below the trigger |
Exposed Methods
| Method | Description |
|---|---|
submit() | Manually upload all files with status: 'ready' (when autoUpload is false) |
trigger() | Programmatically open the file picker dialog |
UploadFile Interface
ts
interface UploadFile {
uid: string // Unique identifier
name: string // File name
size?: number // File size in bytes
type?: string // MIME type
status: 'ready' | 'uploading' | 'success' | 'error'
percent?: number // Upload progress (0-100)
url?: string // File URL (for pre-existing files)
thumbUrl?: string // Thumbnail URL (auto-generated for images)
raw?: File // Original File object
response?: any // Server response
error?: string // Error message
}UploadRequestOptions Interface
ts
interface UploadRequestOptions {
file: File
onProgress: (percent: number) => void
onSuccess: (response: any) => void
onError: (error: string) => void
}