Skip to content

Custom Filtering

vue-superselect filters options automatically as the user types. The built-in filter matches case-insensitively against each option's label. For domain-specific matching, you can provide your own filter function.

Default Filtering

Out of the box, typing in the input filters the visible options. The built-in filter:

  • Matches case-insensitively against the option's label
  • Shows all options when the input is empty
  • Handles IME composition automatically (filtering waits until composition completes)
Default Filter Behavior

No configuration is needed. Filtering is built in. If the input contains text, only matching options are shown. The SelectEmpty component displays a message when no options match.

Custom Filter Function

Pass a filter prop to SelectRoot to replace the built-in matching logic. The filter function receives a collection item and the current query, and returns true to show the option or false to hide it.

Custom Filter with Debounce

Writing a Filter Function

The filter function signature:

ts
type FilterFn<T> = (item: CollectionItem<T>, query: string) => boolean

Each item has these properties:

PropertyTypeDescription
idstringUnique identifier for the option
valueTThe raw value passed to :value on SelectOption
labelstringThe label string used for display
disabledbooleanWhether the option is disabled

Example: search both the option label and a category field:

vue
<script setup>
import { ref } from 'vue'
import { SelectRoot, type FilterFn } from 'vue-superselect'

const tools = [
  { id: 'vite', name: 'Vite', category: 'Build Tool' },
  { id: 'vitest', name: 'Vitest', category: 'Test Runner' },
]

const customFilter: FilterFn<unknown> = (item, query) => {
  const q = query.trim().toLowerCase()
  if (!q) return true

  const tool = tools.find((t) => t.id === item.value)
  const category = tool?.category.toLowerCase() ?? ''

  return item.label.toLowerCase().includes(q) || category.includes(q)
}
</script>

<template>
  <SelectRoot :filter="customFilter" :items="tools" label-key="name" value-key="id">
    <!-- ... -->
  </SelectRoot>
</template>

Debounced Filtering

Use the debounce prop to delay filtering while the user is still typing. This is useful when your filter function is expensive or when you want to reduce visual noise during fast typing.

template
<SelectRoot :filter="customFilter" :debounce="200">
  <!-- ... -->
</SelectRoot>

The debounce value is in milliseconds. The filter function is only called after the user stops typing for that duration.

IME Composition

vue-superselect handles IME (Input Method Editor) composition automatically. When a user is composing characters (e.g., typing Chinese, Japanese, or Korean), filtering is paused until composition is complete. This prevents partial composition strings from triggering unexpected filter results.

No configuration is needed. This behavior is built in.

Next Steps