Skip to content

Slots

To ensure maximum flexibility, this component provides multiple <slot />s in order to allow for more customization.

INFO

If you are not familiar with Vue's slots, you can read more about them here.

option

Type:

ts
slotProps: {
  option: Option;
  index: number;
  isFocused: boolean;
  isSelected: boolean;
  isDisabled: boolean;
}

Customize the rendered template of an option inside the menu. You can use the slot props to retrieve the current menu option that will be rendered in order to have more context and flexbility.

vue
<template>
  <VueSelect v-model="option" :options="options">
    <template #option="{ option, index }">
      {{ option.label }} - {{ option.value }} (#{{ index }})
    </template>
  </VueSelect>
</template>

value

Type: slotProps: { option: Option }

Customize the rendered template if a selected option (inside the select control). You can use the slot props to retrieve the current selected option.

vue
<template>
  <VueSelect v-model="option" :options="options">
    <template #value="{ option }">
      My value is: {{ option.value }}
    </template>
  </VueSelect>
</template>

tag

Type: slotProps: { option: Option, removeOption: () => void }

When using isMulti prop, customize the rendered template of a selected option. You can use the slot props to retrieve the current selected option and a function to remove it.

vue
<template>
  <VueSelect
    v-model="option"
    :options="options"
    :is-multi="true"
  >
    <template #tag="{ option, removeOption }">
      <span>{{ option.label }} <button type="button" @click="removeOption">&times;</button></span>
    </template>
  </VueSelect>
</template>

Type: slotProps: {}

Customize the rendered template for the menu header. This slot is placed before the options.

vue
<template>
  <VueSelect v-model="option" :options="options">
    <template #menu-header>
      <div>
        <h3>My custom header</h3>
      </div>
    </template>
  </VueSelect>
</template>

Type: slotProps: { defaultContent: JSX.Element }

Wrap the entire menu content with a custom container without disrupting the default behavior. This slot is particularly useful for implementing advanced scrolling techniques such as:

  • Virtual scrolling for large option lists
  • Infinite scrolling to dynamically load more options
  • Custom scrollbars or scroll behavior
  • Any other UI enhancements that need to wrap the menu options

The defaultContent prop is a render function that returns all the default menu content (options, no-options message, etc.). You must call this function within your custom implementation to preserve the component's original content and functionality.

vue
<template>
  <VueSelect v-model="option" :options="options">
    <template #menu-container="{ defaultContent }">
      <MyVirtualScroller>
        <!-- Render the default menu content inside your custom container -->
        <component :is="defaultContent" />
      </MyVirtualScroller>
    </template>
  </VueSelect>
</template>

TIP

This slot doesn't replace individual option customization. For that, use the option slot. The menu-container slot is specifically for wrapping the entire menu content.

no-options

Type: slotProps: {}

Customize the rendered template when there are no options matching the search, inside the menu.

vue
<template>
  <VueSelect v-model="option" :options="options">
    <template #no-options>
      No options found.
    </template>
  </VueSelect>
</template>

Type: slotProps: {}

Customize the rendered template for the dropdown icon. Please note that the slot is placed inside the button, so you don't have to deal with attaching event-listeners.

vue
<template>
  <VueSelect v-model="option" :options="options">
    <template #dropdown>
      <MyCustomIcon />
    </template>
  </VueSelect>
</template>

clear

Type: slotProps: {}

Customize the rendered template for the clear icon. Please note that the slot is placed inside the button, so you don't have to deal with attaching event-listeners.

vue
<template>
  <VueSelect v-model="option" :options="options">
    <template #clear>
      <MyCustomIcon />
    </template>
  </VueSelect>
</template>

loading

Type: slotProps: {}

Customize the rendered template when the select component is in a loading state. By default, it displays a <Spinner /> component.

vue
<template>
  <VueSelect
    v-model="option"
    :options="options"
    :is-loading="true"
  >
    <template #loading>
      <MyCustomLoadingComponent />
    </template>
  </VueSelect>
</template>

taggable-no-options

Type: slotProps: { value: string }

Customize the rendered template when there are no matching options and the taggable prop is set to true. You can use the slot props to retrieve the current search value.

vue
<template>
  <VueSelect
    v-model="option"
    :options="options"
    :taggable="true"
  >
    <template #taggable-no-options="{ value }">
      Press enter to add {{ value }} option
    </template>
  </VueSelect>
</template>