Skip to main content

VSelect

The VSelect component provides a dropdown menu for selecting one or more items from a list. It includes keyboard navigation, search filtering, and virtual scrolling for performance.

Basic Usage

<template>
  <VSelect
    v-model="selected"
    :items="items"
    label="Select an item"
  />
</template>

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

const selected = ref(null)
const items = ['California', 'Colorado', 'Florida', 'Georgia', 'Texas']
</script>

Props

items
readonly any[]
Array of items to display in the dropdown.
itemTitle
string | function
Property name or function to determine the display text for each item.
itemValue
string | function
Property name or function to determine the value for each item.
returnObject
boolean
default:"false"
Return the entire item object as the value instead of just the item value.
multiple
boolean
default:"false"
Allow multiple item selection.
chips
boolean
default:"false"
Display selected items as chips.
closableChips
boolean
default:"false"
Allow chips to be closed/removed.
hideSelected
boolean
default:"false"
Hide selected items from the list.
hideNoData
boolean
default:"false"
Hide the menu when there are no items to display.
menuIcon
string
default:"$dropdown"
Icon to display for the dropdown menu indicator.
noDataText
string
default:"$vuetify.noDataText"
Text to display when no items are available.
eager
boolean
default:"false"
Render the menu content immediately instead of lazy loading.
openOnClear
boolean
default:"false"
Open the menu when the clear icon is clicked.

Multiple Selection

<template>
  <VSelect
    v-model="selected"
    :items="items"
    label="Select multiple"
    multiple
    chips
    closable-chips
  />
</template>

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

const selected = ref([])
const items = ['Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5']
</script>

Object Items

<template>
  <VSelect
    v-model="selected"
    :items="items"
    item-title="name"
    item-value="id"
    label="Select a user"
  />
</template>

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

const selected = ref(null)
const items = [
  { id: 1, name: 'John Doe', role: 'Admin' },
  { id: 2, name: 'Jane Smith', role: 'User' },
  { id: 3, name: 'Bob Johnson', role: 'Manager' },
]
</script>

Return Object

<template>
  <div>
    <VSelect
      v-model="selected"
      :items="items"
      item-title="name"
      item-value="id"
      label="Select a user"
      return-object
    />
    
    <p v-if="selected">
      Selected: {{ selected.name }} ({{ selected.role }})
    </p>
  </div>
</template>

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

const selected = ref(null)
const items = [
  { id: 1, name: 'John Doe', role: 'Admin' },
  { id: 2, name: 'Jane Smith', role: 'User' },
]
</script>

Keyboard Navigation

The select supports keyboard navigation:
  • Enter/Space/ArrowDown: Open menu
  • Escape/Tab: Close menu
  • ArrowUp/ArrowDown: Navigate items
  • Home/End: Jump to first/last item
  • Type letters: Jump to item starting with those letters
<template>
  <VSelect
    v-model="selected"
    :items="['Apple', 'Banana', 'Cherry', 'Date', 'Elderberry']"
    label="Try keyboard navigation"
  />
</template>

Custom Item Display

<template>
  <VSelect
    v-model="selected"
    :items="items"
    item-title="name"
    item-value="id"
    label="Select a user"
  >
    <template #item="{ item, props }">
      <VListItem v-bind="props">
        <template #prepend>
          <VAvatar :color="item.raw.color">
            {{ item.raw.name[0] }}
          </VAvatar>
        </template>
        <template #title>
          {{ item.raw.name }}
        </template>
        <template #subtitle>
          {{ item.raw.email }}
        </template>
      </VListItem>
    </template>
  </VSelect>
</template>

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

const selected = ref(null)
const items = [
  { id: 1, name: 'John Doe', email: '[email protected]', color: 'blue' },
  { id: 2, name: 'Jane Smith', email: '[email protected]', color: 'green' },
]
</script>
<template>
  <VSelect
    v-model="selected"
    v-model:search="search"
    :items="filteredItems"
    label="Search and select"
  />
</template>

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

const selected = ref(null)
const search = ref('')
const allItems = ['Apple', 'Banana', 'Cherry', 'Date', 'Elderberry']

const filteredItems = computed(() => {
  if (!search.value) return allItems
  return allItems.filter(item => 
    item.toLowerCase().includes(search.value.toLowerCase())
  )
})
</script>

Events

update:modelValue
(value: any) => void
Emitted when the selected value changes.
update:menu
(value: boolean) => void
Emitted when the menu opens or closes.
Emitted when the search query changes.
update:focused
(focused: boolean) => void
Emitted when the input focus state changes.

Slots

item
{ item, index, props }
Customize the appearance of list items.
chip
{ item, index, props }
Customize the appearance of selected chips.
selection
{ item, index }
Customize how selected items are displayed.
no-data
{}
Content to display when no items are available.
prepend-item
{}
Content to display before the list items.
append-item
{}
Content to display after the list items.

Build docs developers (and LLMs) love