Upload
File upload component with 4 display modes: drag zone, button trigger, picture-card, and avatar. Built-in upload status management, auto/manual upload, image thumbnail preview, type/size validation, custom hooks, i18n, and slot customization.
Basic Usage (Drag Mode)
Drag files onto the dashed area or click to select.
Show Code
<script setup lang="ts">
import { ref } from 'vue'
import { TUpload } from '@gulcc/tabler-vue'
const file = ref(null)
</script>
<template>
<TUpload v-model="file" />
</template>Button Mode
Click the button to trigger the file picker — ideal for forms and toolbars.
Show Code
<TUpload v-model="files" list-type="button" title="Upload" />Picture-card Mode
Images display as a thumbnail grid. Hover to show preview / remove actions.
Show Code
<TUpload v-model="files" list-type="picture-card" multiple accept="image/*" />Avatar Mode
Circular upload container, great for profile pictures.
Show Code
<TUpload list-type="avatar" title="Upload avatar" accept="image/*" />Multi File
Set multiple to allow selecting multiple files at once.
Show Code
<TUpload v-model="files" multiple />Custom Title & Description
Use title and description to customize the drop zone prompt.
Show Code
<TUpload v-model="file" title="Upload product image" description="JPG, PNG" />Max Count
max-count limits the number of selectable files.
Show Code
<TUpload v-model="files" multiple :max-count="3" />Custom Validation
beforeUpload hook runs before upload. Return true to pass, or a string to show an error.
Show Code
<TUpload
v-model="file"
:before-upload="(file) => file.size > 1024 ? 'File too large' : true"
/>Localization
Use locale to override text strings — supports full i18n.
Show Code
<TUpload
v-model="files"
:locale="{
dropTitle: 'Drag & drop files here',
clearAll: 'Clear all',
}"
/>Disabled State
Show Code
<TUpload v-model="file" disabled />File Status Display
Four statuses: pending (waiting), uploading (progress bar), done (success), error (error message).
Show Code
<TUpload v-model="files" list-type="button" />Status is controlled via UploadFileInfo.status. Error details are shown via errorMessage.
Draft Preload
Pass pre-existing files with status: 'done' or status: 'error' directly via v-model.
Show Code
<script setup lang="ts">
const draftFiles = ref([
{ uid: '1', name: 'contract.pdf', size: 1280000, status: 'done', url: '...' },
{ uid: '2', name: 'image.png', size: 2560000, status: 'done', url: '...' },
])
</script>
<TUpload v-model="draftFiles" list-type="button" />Button Props Passthrough
upload-button-props passes arbitrary attributes to the trigger button in button mode.
Show Code
<TUpload
list-type="button"
title="Upload"
:upload-button-props="{ class: 'btn-pill btn-outline-danger' }"
/>Custom Action Buttons
Use the #actions slot to replace the default action buttons. Exposes { file, fileList, actions }.
Show Code
<TUpload v-model="files" list-type="button">
<template #actions="{ file, fileList, actions }">
<button @click="actions.preview">Preview</button>
<button @click="actions.remove">Delete</button>
<button @click="handleCustom(file)">Edit</button>
</template>
</TUpload>API
Props
| Prop | Type | Default | Description |
|---|---|---|---|
v-model | UploadFileInfo | UploadFileInfo[] | null | null | Selected file(s) |
list-type | 'drag' | 'button' | 'picture-card' | 'avatar' | 'drag' | Display mode |
accept | string | — | Accepted MIME types, e.g. 'image/*,.pdf' |
max-size | number | — | Max file size in bytes |
max-count | number | — | Max file count (multiple mode) |
multiple | boolean | false | Allow multiple files |
disabled | boolean | false | Disabled |
title | string | — | Title text |
description | string | — | Description text |
action | string | — | Upload URL (POST multipart/form-data) |
name | string | 'file' | Form field name |
method | string | 'post' | HTTP method |
headers | Record<string, string> | — | Custom request headers |
data | object | (file) => object | — | Extra form data |
with-credentials | boolean | false | Send cookies with request |
directory | boolean | false | Enable folder upload |
auto-upload | boolean | true | Auto upload after selection |
show-upload-list | boolean | { showPreviewIcon, showRemoveIcon, showDownloadIcon } | true | Show/hide file list |
open-file-dialog-on-click | boolean | true | Click to open dialog |
preview | boolean | true | Generate image thumbnails |
before-upload | (file, fileList) => boolean | string | Promise | — | Pre-upload validation |
on-before-remove | (file) => boolean | Promise | — | Pre-remove hook |
custom-request | (file, onProgress, onSuccess, onError) => void | — | Custom upload logic |
is-image-url | (file) => boolean | — | Custom image detection |
preview-file | (file) => Promise<string> | — | Custom preview generation |
upload-button-props | Record<string, any> | — | Attributes passed to trigger button |
locale | Partial<UploadLocale> | Chinese | i18n overrides |
size-error-message | string | — | Size error text |
type-error-message | string | — | Type error text |
UploadLocale
| Key | Default | Description |
|---|---|---|
dropTitle | '拖拽文件到此处' | Empty state title |
dropDescription | '或点击此处选择文件' | Empty state description |
releaseToUpload | '释放以上传文件' | Drag hover prompt |
selectedCount | '已选择 {count} 个文件' | File count (replace {count}) |
clearAll | '清除全部' | Clear button |
continueAdd | '继续添加文件' | Add more button |
retry | '重新选择' | Retry button |
sizeError | '文件大小超出限制' | Size validation error |
typeError | '文件类型不允许' | Type validation error |
uploadBtn | '上传' | Upload button text |
preview | '预览' | Preview tooltip |
download | '下载' | Download tooltip |
uploadSuccess | '上传成功' | Status label |
uploadFailed | '上传失败' | Status label |
uploading | '上传中' | Status label |
UploadFileInfo
| Field | Type | Description |
|---|---|---|
uid | string | Unique ID |
name | string | File name |
size | number | Size in bytes |
type | string | MIME type |
file | File | Native File reference |
status | 'pending' | 'uploading' | 'done' | 'error' | Upload status |
percent | number | Progress 0-100 |
thumbUrl | string | Thumbnail blob URL |
url | string | External access URL |
response | any | Upload response data |
errorMessage | string | Error details |
Slots
| Slot | Scope | Description |
|---|---|---|
icon | — | Drop zone icon (drag/button mode) |
title | — | Title text |
description | — | Description text |
iconRender | { file: UploadFileInfo } | Custom file type icon |
itemRender | { file, fileList, actions: { preview, remove, download } } | Full list item customization |
actions | { file, fileList, actions: { preview, remove, download } } | Custom action buttons |
Emits
| Event | Payload | Description |
|---|---|---|
update:modelValue | (value) | v-model update |
change | { file: UploadFileInfo, fileList: UploadFileInfo[] } | File change |
error | (message: string) | Validation error |
preview | (file: UploadFileInfo) | Preview button click |
remove | (file: UploadFileInfo) | File removed |
download | (file: UploadFileInfo) | Download button click |
success | (file: UploadFileInfo) | Upload success |
dblclick | (file: UploadFileInfo) | Double-click list item |