Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/vuetifyjs/vuetify/llms.txt

Use this file to discover all available pages before exploring further.

Data Table

The VDataTable component is used for displaying tabular data. It includes features such as sorting, searching, pagination, row selection, expandable rows, and grouping.

Usage

<template>
  <v-data-table
    :headers="headers"
    :items="desserts"
  />
</template>

<script setup>
const headers = [
  { title: 'Dessert', key: 'name' },
  { title: 'Calories', key: 'calories' },
  { title: 'Fat (g)', key: 'fat' },
]

const desserts = [
  { name: 'Frozen Yogurt', calories: 159, fat: 6.0 },
  { name: 'Ice cream sandwich', calories: 237, fat: 9.0 },
  { name: 'Eclair', calories: 262, fat: 16.0 },
]
</script>

Props

headers
DataTableHeader[]
Array of header definitions. Each header can have: title, key, value, sortable, align, width, minWidth, maxWidth, fixed, sort, filter
items
any[]
Array of data items to display in the table
itemValue
string | function
default:"id"
Property or function to use as the unique identifier for each item
Text to filter the items
sortBy
SortItem[]
Array of sort configurations. Each item has key and order (asc or desc)
multiSort
boolean
default:"false"
Allows sorting by multiple columns
mustSort
boolean
default:"false"
Requires at least one sort to be active
page
number
default:"1"
Current page number
itemsPerPage
number
default:"10"
Number of items to display per page. Use -1 for all items
showSelect
boolean
default:"false"
Shows checkboxes for row selection
selectStrategy
string
default:"page"
Selection strategy. Options: single, page, all
modelValue
any[]
Array of selected items (v-model)
showExpand
boolean
default:"false"
Shows expand icon for expandable rows
expanded
any[]
Array of expanded items
groupBy
GroupByItem[]
Array of grouping configurations. Each item has key and order
loading
boolean | string
default:"false"
Shows a loading indicator. Can be a boolean or loading text
loadingText
string
default:"$vuetify.dataIterator.loadingText"
Text to display when loading
noDataText
string
default:"$vuetify.noDataText"
Text to display when there are no items
hideNoData
boolean
default:"false"
Hides the no data message
hideDefaultHeader
boolean
default:"false"
Hides the default header
Hides the default pagination footer
hideDefaultBody
boolean
default:"false"
Hides the default table body
fixedHeader
boolean
default:"false"
Makes the header fixed while scrolling
Makes the footer fixed
height
string | number
Sets the height of the table (enables scrolling)
hover
boolean
default:"false"
Adds hover effect on table rows
density
string
default:"default"
Adjusts row height. Options: default, comfortable, compact

Events

update:modelValue
(items: any[]) => void
Emitted when selected items change
update:page
(page: number) => void
Emitted when page changes
update:itemsPerPage
(count: number) => void
Emitted when items per page changes
update:sortBy
(sortBy: any[]) => void
Emitted when sort configuration changes
update:groupBy
(groupBy: any[]) => void
Emitted when grouping changes
update:expanded
(expanded: any[]) => void
Emitted when expanded items change

Slots

Slot for content above the table
item.{key}
Slot for customizing individual column cells. Replace {key} with the column key
header.{key}
Slot for customizing individual header cells
expanded-row
Slot for content shown when a row is expanded
no-data
Slot for custom no data message
loading
Slot for custom loading indicator
bottom
Slot for content below the table (replaces default footer)

Examples

Basic Table

<template>
  <v-data-table
    :headers="headers"
    :items="users"
    :items-per-page="5"
  />
</template>

<script setup>
const headers = [
  { title: 'Name', key: 'name', align: 'start' },
  { title: 'Email', key: 'email' },
  { title: 'Role', key: 'role' },
  { title: 'Status', key: 'status' },
]

const users = [
  { id: 1, name: 'John Doe', email: 'john@example.com', role: 'Admin', status: 'Active' },
  { id: 2, name: 'Jane Smith', email: 'jane@example.com', role: 'User', status: 'Active' },
  { id: 3, name: 'Bob Johnson', email: 'bob@example.com', role: 'User', status: 'Inactive' },
]
</script>

Sortable Table

<template>
  <v-data-table
    :headers="headers"
    :items="products"
    :sort-by="[{ key: 'price', order: 'desc' }]"
    multi-sort
  />
</template>

<script setup>
const headers = [
  { title: 'Product', key: 'name', sortable: true },
  { title: 'Price', key: 'price', sortable: true },
  { title: 'Stock', key: 'stock', sortable: true },
  { title: 'Category', key: 'category', sortable: false },
]

const products = [
  { name: 'Laptop', price: 999, stock: 15, category: 'Electronics' },
  { name: 'Mouse', price: 25, stock: 100, category: 'Accessories' },
  { name: 'Keyboard', price: 75, stock: 50, category: 'Accessories' },
]
</script>

Selectable Rows

<template>
  <div>
    <v-data-table
      v-model="selected"
      :headers="headers"
      :items="items"
      show-select
      item-value="id"
    />
    <div class="mt-4">
      Selected: {{ selected.length }} items
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const selected = ref([])

const headers = [
  { title: 'Name', key: 'name' },
  { title: 'Email', key: 'email' },
]

const items = [
  { id: 1, name: 'Alice', email: 'alice@example.com' },
  { id: 2, name: 'Bob', email: 'bob@example.com' },
  { id: 3, name: 'Charlie', email: 'charlie@example.com' },
]
</script>

Custom Cell Slots

<template>
  <v-data-table
    :headers="headers"
    :items="users"
  >
    <template v-slot:item.status="{ item }">
      <v-chip
        :color="item.status === 'Active' ? 'success' : 'error'"
        size="small"
      >
        {{ item.status }}
      </v-chip>
    </template>
    
    <template v-slot:item.actions="{ item }">
      <v-btn
        icon="mdi-pencil"
        size="small"
        variant="text"
        @click="editItem(item)"
      />
      <v-btn
        icon="mdi-delete"
        size="small"
        variant="text"
        @click="deleteItem(item)"
      />
    </template>
  </v-data-table>
</template>

<script setup>
const headers = [
  { title: 'Name', key: 'name' },
  { title: 'Status', key: 'status' },
  { title: 'Actions', key: 'actions', sortable: false },
]

const users = [
  { id: 1, name: 'John Doe', status: 'Active' },
  { id: 2, name: 'Jane Smith', status: 'Inactive' },
]

function editItem(item) {
  console.log('Edit', item)
}

function deleteItem(item) {
  console.log('Delete', item)
}
</script>

Expandable Rows

<template>
  <v-data-table
    :headers="headers"
    :items="orders"
    show-expand
  >
    <template v-slot:expanded-row="{ item }">
      <tr>
        <td :colspan="headers.length + 1">
          <div class="pa-4">
            <strong>Order Details:</strong>
            <p>Customer: {{ item.customer }}</p>
            <p>Address: {{ item.address }}</p>
            <p>Notes: {{ item.notes }}</p>
          </div>
        </td>
      </tr>
    </template>
  </v-data-table>
</template>

<script setup>
const headers = [
  { title: 'Order ID', key: 'id' },
  { title: 'Date', key: 'date' },
  { title: 'Total', key: 'total' },
]

const orders = [
  { 
    id: '1001', 
    date: '2024-01-15', 
    total: '$150.00',
    customer: 'John Doe',
    address: '123 Main St',
    notes: 'Deliver after 5 PM'
  },
  { 
    id: '1002', 
    date: '2024-01-16', 
    total: '$89.99',
    customer: 'Jane Smith',
    address: '456 Oak Ave',
    notes: 'Ring doorbell'
  },
]
</script>

Grouped Table

<template>
  <v-data-table
    :headers="headers"
    :items="employees"
    :group-by="[{ key: 'department', order: 'asc' }]"
  />
</template>

<script setup>
const headers = [
  { title: 'Name', key: 'name' },
  { title: 'Position', key: 'position' },
  { title: 'Department', key: 'department' },
]

const employees = [
  { name: 'Alice Johnson', position: 'Developer', department: 'Engineering' },
  { name: 'Bob Smith', position: 'Designer', department: 'Design' },
  { name: 'Charlie Brown', position: 'Developer', department: 'Engineering' },
  { name: 'Diana Prince', position: 'Manager', department: 'Design' },
]
</script>

Build docs developers (and LLMs) love