Skip to main content

List

The VList component is used to display a collection of items. It can contain multiple list items, sub-lists, dividers, and subheaders. Lists support navigation, selection, and various styling options.

Usage

<template>
  <v-list>
    <v-list-item title="Item 1" />
    <v-list-item title="Item 2" />
    <v-list-item title="Item 3" />
  </v-list>
</template>

Props

items
any[]
Array of items to display. Each item can be a string or object with properties like title, value, props
itemTitle
string | function
default:"title"
Property name or function to use for item titles
itemValue
string | function
default:"value"
Property name or function to use for item values
itemChildren
string | function
default:"children"
Property name or function for nested children items
itemProps
string | function | boolean
Property name, function, or true to pass all props to list items
lines
string | boolean
default:"one"
Number of lines to display. Options: one, two, three, false
nav
boolean
default:"false"
Applies navigation list styling (reduces width and rounds corners)
slim
boolean
default:"false"
Reduces horizontal spacing
disabled
boolean
default:"false"
Disables all list item interactions
density
string
Adjusts vertical spacing. Options: default, comfortable, compact
bgColor
string
Background color of the list
color
string
Color applied to active/selected items
activeColor
string
Color for active items (deprecated, use color instead)
baseColor
string
Base color for inactive items
activeClass
string
CSS class applied to active items
selected
any[]
Array of selected item values (v-model)
opened
any[]
Array of opened/expanded item values
selectStrategy
string
default:"single-leaf"
Selection strategy. Options: single-leaf, leaf, independent, single-independent, classic
openStrategy
string
default:"list"
Strategy for opening nested items. Options: list, single, multiple
expandIcon
IconValue
Icon to show for expandable items
collapseIcon
IconValue
Icon to show for collapsible items
navigationStrategy
string
default:"focus"
Keyboard navigation strategy. Options: focus, track
navigationIndex
number
Current navigation index
prependGap
string | number
Gap before prepend content
indent
string | number
Indentation for nested items
border
string | number | boolean
Border styles
elevation
string | number
Elevation level (0-24)
rounded
string | number | boolean
Border radius
variant
string
default:"text"
Variant style. Options: flat, text, elevated, tonal, outlined, plain

Events

update:selected
(value: any[]) => void
Emitted when selection changes
update:opened
(value: any[]) => void
Emitted when opened items change
click:open
(value: object) => void
Emitted when an item is opened/closed. Receives { id, value, path }
click:select
(value: object) => void
Emitted when an item is selected. Receives { id, value, path }

Slots

default
Default slot for list items
Slot for customizing individual list items
header
Slot for list header content
Slot for item titles
subtitle
Slot for item subtitles
prepend
Slot for content before item text
append
Slot for content after item text

Examples

Basic List

<template>
  <v-list>
    <v-list-item
      v-for="item in items"
      :key="item.title"
      :title="item.title"
      :subtitle="item.subtitle"
    />
  </v-list>
</template>

<script setup>
const items = [
  { title: 'Home', subtitle: 'Go to homepage' },
  { title: 'Profile', subtitle: 'View your profile' },
  { title: 'Settings', subtitle: 'Configure your account' },
]
</script>

List with Icons

<template>
  <v-list>
    <v-list-item
      v-for="item in menuItems"
      :key="item.title"
      :title="item.title"
      :prepend-icon="item.icon"
      :to="item.to"
    />
  </v-list>
</template>

<script setup>
const menuItems = [
  { title: 'Dashboard', icon: 'mdi-view-dashboard', to: '/dashboard' },
  { title: 'Messages', icon: 'mdi-message', to: '/messages' },
  { title: 'Profile', icon: 'mdi-account', to: '/profile' },
  { title: 'Settings', icon: 'mdi-cog', to: '/settings' },
]
</script>
<template>
  <v-list nav>
    <v-list-item
      v-for="item in navItems"
      :key="item.title"
      :title="item.title"
      :prepend-icon="item.icon"
      :value="item.value"
      color="primary"
    />
  </v-list>
</template>

<script setup>
const navItems = [
  { title: 'Home', icon: 'mdi-home', value: 'home' },
  { title: 'About', icon: 'mdi-information', value: 'about' },
  { title: 'Contact', icon: 'mdi-email', value: 'contact' },
]
</script>

List with Avatars

<template>
  <v-list>
    <v-list-item
      v-for="user in users"
      :key="user.id"
      :title="user.name"
      :subtitle="user.email"
      :prepend-avatar="user.avatar"
    >
      <template v-slot:append>
        <v-btn icon="mdi-message" variant="text" />
      </template>
    </v-list-item>
  </v-list>
</template>

<script setup>
const users = [
  { id: 1, name: 'John Doe', email: '[email protected]', avatar: '/john.jpg' },
  { id: 2, name: 'Jane Smith', email: '[email protected]', avatar: '/jane.jpg' },
]
</script>

Selectable List

<template>
  <v-list
    v-model:selected="selected"
    select-strategy="classic"
  >
    <v-list-item
      v-for="item in items"
      :key="item.value"
      :title="item.title"
      :value="item.value"
    />
  </v-list>
</template>

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

const selected = ref(['item1'])

const items = [
  { title: 'Item 1', value: 'item1' },
  { title: 'Item 2', value: 'item2' },
  { title: 'Item 3', value: 'item3' },
]
</script>

Nested List

<template>
  <v-list
    :items="items"
    :opened="opened"
  />
</template>

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

const opened = ref(['users'])

const items = [
  {
    title: 'Users',
    value: 'users',
    children: [
      { title: 'John Doe', value: 'john' },
      { title: 'Jane Smith', value: 'jane' },
    ],
  },
  {
    title: 'Settings',
    value: 'settings',
    children: [
      { title: 'Profile', value: 'profile' },
      { title: 'Security', value: 'security' },
    ],
  },
]
</script>

List with Dividers

<template>
  <v-list>
    <v-list-item title="Item 1" />
    <v-list-item title="Item 2" />
    <v-divider />
    <v-list-subheader>Section 2</v-list-subheader>
    <v-list-item title="Item 3" />
    <v-list-item title="Item 4" />
  </v-list>
</template>

Multi-line List

<template>
  <v-list lines="two">
    <v-list-item
      v-for="item in notifications"
      :key="item.id"
      :title="item.title"
      :subtitle="item.message"
      :prepend-icon="item.icon"
    >
      <template v-slot:append>
        <div class="text-caption">{{ item.time }}</div>
      </template>
    </v-list-item>
  </v-list>
</template>

<script setup>
const notifications = [
  { 
    id: 1, 
    title: 'New message', 
    message: 'You have a new message from John',
    icon: 'mdi-email',
    time: '2m ago'
  },
  { 
    id: 2, 
    title: 'Update available', 
    message: 'A new version is ready to install',
    icon: 'mdi-update',
    time: '1h ago'
  },
]
</script>

Build docs developers (and LLMs) love