Skip to main content

File Upload

This is a Labs component. The API may change in future releases. Import from vuetify/labs/VFileUpload.
The VFileUpload component creates an intuitive file upload interface with drag-and-drop support, file filtering, and item display.

Usage

<template>
  <v-file-upload
    v-model="files"
    label="Upload Files"
    multiple
  />
</template>

<script setup>
import { ref } from 'vue'
import { VFileUpload } from 'vuetify/labs/VFileUpload'

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

API

Props

modelValue
File | File[]
The selected file(s).
multiple
boolean
default:"false"
Allows selecting multiple files.
title
string
default:"$vuetify.fileUpload.title"
Title displayed in the upload area.
subtitle
string
Subtitle displayed below the browse button.
browseText
string
default:"$vuetify.fileUpload.browse"
Text for the browse button.
dividerText
string
default:"$vuetify.fileUpload.divider"
Text displayed in the divider.
icon
string
default:"$upload"
Icon displayed in the upload area.
disabled
boolean
default:"false"
Disables file selection.
clearable
boolean
default:"false"
Shows a clear button on each file item.
hideBrowse
boolean
default:"false"
Hides the browse button (drag-and-drop only).
showSize
boolean
default:"false"
Displays file sizes in the file list.
scrim
boolean | string
default:"true"
Shows a scrim overlay when dragging files.
name
string
Name attribute for the file input.
filterByType
string
Filter files by MIME type (e.g., “image/*”, “application/pdf”).

Events

update:modelValue
(files: File[]) => void
Emitted when the file selection changes.
rejected
(files: File[]) => void
Emitted when files are rejected due to filtering.

Slots

default
Default content (hidden by default).
icon
Customize the upload icon.
title
Customize the title text.
divider
Customize the divider section.
browse
{ props }
Customize the browse button.
input
{ inputNode }
Access or replace the file input element.
item
{ file, props }
Customize individual file item display.

Examples

Image Upload Only

<template>
  <v-file-upload
    v-model="images"
    filter-by-type="image/*"
    multiple
    title="Upload Images"
  />
</template>

<script setup>
import { ref } from 'vue'
import { VFileUpload } from 'vuetify/labs/VFileUpload'

const images = ref([])
</script>

With File Size Display

<template>
  <v-file-upload
    v-model="files"
    show-size
    clearable
    multiple
  />
</template>

Drag-and-Drop Only

<template>
  <v-file-upload
    v-model="files"
    hide-browse
    title="Drop files here"
    subtitle="Drag and drop only"
  />
</template>

Custom Styling

<template>
  <v-file-upload
    v-model="files"
    color="primary"
    variant="outlined"
    rounded="lg"
  />
</template>

File Validation

<template>
  <v-file-upload
    v-model="files"
    @rejected="onRejected"
    filter-by-type="application/pdf"
  />
</template>

<script setup>
import { ref } from 'vue'
import { VFileUpload } from 'vuetify/labs/VFileUpload'

const files = ref([])

function onRejected(rejectedFiles) {
  console.log('Rejected files:', rejectedFiles)
  alert(`${rejectedFiles.length} file(s) rejected. Only PDF files are allowed.`)
}
</script>

Custom File Items

<template>
  <v-file-upload v-model="files" multiple>
    <template #item="{ file }">
      <v-card class="mb-2">
        <v-card-text>
          <div class="d-flex align-center">
            <v-icon class="mr-2">mdi-file</v-icon>
            <div class="flex-grow-1">
              <div>{{ file.name }}</div>
              <div class="text-caption">{{ formatSize(file.size) }}</div>
            </div>
          </div>
        </v-card-text>
      </v-card>
    </template>
  </v-file-upload>
</template>

<script setup>
import { ref } from 'vue'
import { VFileUpload } from 'vuetify/labs/VFileUpload'

const files = ref([])

function formatSize(bytes) {
  if (bytes === 0) return '0 Bytes'
  const k = 1024
  const sizes = ['Bytes', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i]
}
</script>

Compact Density

<template>
  <v-file-upload
    v-model="files"
    density="compact"
    multiple
  />
</template>

Build docs developers (and LLMs) love