Introduction to Vue Select
Vue Select is a powerful, lightweight Vue.js component that provides everything developers wish the native HTML select element could do. Unlike native selects that offer limited functionality, Vue Select delivers a rich, customizable dropdown experience with features like search filtering, multiple selections, tagging, and extensive customization options.
The component ships as a single package that you can drop into any Vue 3 project, and it immediately provides functionality that would require dozens of lines of custom code to implement otherwise. From instant search filtering that helps users find options in long lists, to multiple selection with tag-style chips, to the ability to create new options on the fly through tagging, Vue Select handles these use cases with elegant simplicity.
What sets Vue Select apart is its philosophy of providing sensible defaults while remaining deeply customizable. Out of the box, you get a polished dropdown with search, clear functionality, and keyboard navigation. The component follows Vue's conventions closely, supporting v-model for two-way data binding, providing a comprehensive props API for configuration, and emitting standard events that integrate naturally with your application architecture. For more advanced needs, you can customize label rendering through the label prop, transform values through the reduce prop, filter options through custom callbacks, or even replace internal components entirely through the components API. This combination of powerful defaults and extensive customization makes Vue Select suitable for everything from simple form selects to complex multi-select interfaces in enterprise Vue.js applications.
For complete technical details, refer to the Vue Select Official Documentation as the canonical source for all component behavior and API specifications.
Installation and Setup
Getting Vue Select running in your Vue 3 project requires just a few steps. The component is distributed as an NPM package that you can install alongside your other dependencies. After installation, you register it globally or import it into specific components as needed. The setup process follows standard Vue 3 patterns, meaning it works seamlessly with both the Composition API and the Options API, giving you flexibility in how you structure your components.
Installing via NPM
npm install vue-select
After installation, you'll need to import the CSS to ensure proper styling:
import 'vue-select/dist/vue-select.css'
Global Registration
For global registration in your main.js or App.vue:
import { createApp } from 'vue'
import VSelect from 'vue-select'
import 'vue-select/dist/vue-select.css'
import App from './App.vue'
const app = createApp(App)
app.component('v-select', VSelect)
app.mount('#app')
Local Component Import
Or use it locally in a specific component:
<script setup>
import VSelect from 'vue-select'
import 'vue-select/dist/vue-select.css'
</script>
<template>
<v-select :options="['Vue', 'React', 'Angular']"></v-select>
</template>
The Vue Select installation guide provides comprehensive instructions for various build setups and framework integrations. For additional context on working with APIs and data fetching patterns in JavaScript applications, see our guide on the Fetch API in JavaScript.
Understanding the Options Prop
The options prop forms the foundation of any Vue Select implementation, defining the available choices that users can select from. Vue Select accepts arrays of either primitive values (strings, numbers) or objects, giving you flexibility in how you structure your data. This versatility means you can work with whatever data format your API provides, whether it's simple string arrays for static lists or complex objects representing entities with multiple properties.
Primitive Value Arrays
When you pass an array of primitives, Vue Select automatically uses each value as both the display label and the selected value:
const countries = ['Canada', 'United States', 'Mexico']
Object Arrays with Label Mapping
For complex scenarios, work with arrays of objects. By default, Vue Select looks for a label property:
const options = [
{ label: 'Canada', value: 'CA' },
{ label: 'United States', value: 'US' },
{ label: 'Mexico', value: 'MX' }
]
Use the label prop to map custom property names:
<v-select
:options="countries"
label="countryName"
></v-select>
const countries = [
{ countryName: 'Canada', code: 'CA', region: 'North America' },
{ countryName: 'United States', code: 'US', region: 'North America' }
]
The label prop tells Vue Select which property to use when displaying options. This mapping is essential when working with APIs that use domain-specific property names, as it decouples your component's display logic from the shape of your backend data. The Vue Select options documentation covers primitive and object array handling in detail.
When working with complex object structures, implementing dynamic type validation in TypeScript ensures your data conforms to expected shapes before passing options to Vue Select.
Working with v-model and Selected Values
Vue Select leverages Vue's v-model directive for two-way data binding, making it feel natural to developers already familiar with form handling in Vue. When you bind v-model to a data property, Vue Select automatically keeps that property in sync with the current selection. This synchronization works bidirectionally: selecting an option updates your bound property, and programmatically changing the property updates the displayed selection.
Single Select Mode
For single-select mode, v-model binds to the selected option:
<template>
<v-select v-model="selectedCountry" :options="countries"></v-select>
</template>
<script>
export default {
data() {
return {
selectedCountry: null,
countries: ['Canada', 'United States', 'Mexico']
}
}
}
</script>
Multiple Select Mode
The multiple prop transforms Vue Select into a multi-select component:
<template>
<v-select
v-model="selectedItems"
:options="items"
multiple
></v-select>
</template>
<script>
export default {
data() {
return {
selectedItems: [],
items: ['Vue', 'React', 'Angular', 'Svelte']
}
}
}
</script>
For modern Vue 3 applications using React-style patterns like useActionState, our guide on React useActionState explores similar state management concepts that apply to Vue's reactivity system.
The Vue Select values guide provides complete coverage of v-model binding patterns, single versus multiple selection, and value transformation techniques.
The Reduce Prop for Value Transformation
When your application needs to store only specific values from selected objects rather than the entire object, the reduce prop provides an elegant solution. This powerful prop accepts a callback function that transforms a selected option into whatever value format your application requires.
<template>
<v-select
v-model="countryCode"
:options="countries"
label="countryName"
:reduce="country => country.code"
></v-select>
</template>
<script>
export default {
data() {
return {
countries: [
{ countryName: 'Canada', code: 'CA', region: 'North America' },
{ countryName: 'United States', code: 'US', region: 'North America' },
{ countryName: 'Germany', code: 'DE', region: 'Europe' }
],
countryCode: null
}
}
}
</script>
Common Pitfall: Reduced Values Without Matching Options
A frequent issue occurs when using reduce with initial values that don't correspond to any option. Vue Select searches through the options array, running each option through the reduce function, looking for a match. If your reduce function extracts option.id but your initial v-model is just the numeric ID without the full option object, Vue Select cannot display the selected value correctly. The component displays the raw value rather than the expected label because no matching option exists.
The solution involves ensuring your initial value includes enough information for Vue Select to find the corresponding option. In API-driven applications, this typically means fetching the full option data when editing records, or maintaining the options array with entries that match your stored values. Some applications use computed properties to look up the full option object based on the stored ID, passing that to Vue Select while keeping the reduced value in sync separately.
// Problem: Initial value doesn't match any option after reduction
// reduce: option => option.id
// options have ids 1, 2, 3 but initial value is 'CA' (no match)
// Solution: Ensure initial value corresponds to a reducible option
// Or pre-fetch the full option object when editing existing records
Tagging and Dynamic Option Creation
The taggable prop enables users to create new options that don't exist in the original options array. When enabled, typing in the search input and pressing Enter creates a new option from the search text, adding it to the selected values.
<template>
<v-select
v-model="selectedSkills"
:options="skills"
taggable
multiple
push-tags
></v-select>
</template>
<script>
export default {
data() {
return {
skills: ['JavaScript', 'Vue', 'React', 'TypeScript', 'Node.js'],
selectedSkills: ['Vue', 'JavaScript']
}
}
}
</script>
Custom Option Creation
When combining taggable with complex option objects, define createOption:
<v-select
taggable
multiple
label="title"
:options="books"
:create-option="book => ({ title: book, author: { firstName: '', lastName: '' } })"
:reduce="book => `${book.author.firstName} ${book.author.lastName}`"
></v-select>
The pushTags prop controls whether newly created tags are added to the options array permanently or exist only in the current selection. When combining tagging with the reduce prop, ensure your createOption function returns objects that your reduce function can process correctly. The Vue Select tagging documentation covers taggable, push-tags, and createOption in detail.
Everything you need for powerful dropdown experiences
Search & Filtering
Instant search filtering through options. Users can quickly find what they need in long lists.
Multiple Selection
Select multiple options displayed as chips. Perfect for tags, categories, and multi-choice scenarios.
Tagging Support
Allow users to create new options dynamically. Ideal for custom tags and flexible form inputs.
Value Transformation
The reduce prop lets you transform selected objects into simple values for clean data storage.
Extensive Customization
40+ props for fine-tuned control over behavior, appearance, and interaction patterns.
Accessibility Built-in
WAI-ARIA compliant with RTL support for international applications.
Customization and Configuration Options
Vue Select offers extensive customization through its props API, allowing you to tailor the component's behavior and appearance to match your application's requirements. These props control everything from basic functionality like whether search is enabled, to sophisticated behaviors like how options filter, to styling-related features like placeholder text and clear button visibility.
Common Configuration Props
| Prop | Purpose | Default |
|---|---|---|
searchable | Enable/disable search filtering | true |
clearable | Allow clearing selection | true |
disabled | Disable the component | false |
placeholder | Placeholder text | '' |
multiple | Enable multi-select | false |
closeOnSelect | Close dropdown on selection | true |
Usage Examples
<!-- Non-searchable dropdown for small option sets -->
<v-select
v-model="selection"
:options="smallSet"
:searchable="false"
></v-select>
<!-- With custom placeholder -->
<v-select
v-model="selection"
:options="options"
placeholder="Choose an option..."
></v-select>
<!-- Disabled state for conditional fields -->
<v-select
:value="selection"
:options="options"
disabled
></v-select>
The Vue Select API props reference provides complete documentation for all available props and their configuration options.
Best Practices for Performance
Performance considerations become important when Vue Select handles large option sets or appears frequently in your application. Several patterns help maintain responsive interfaces even with thousands of options.
Stable Option References
Use computed properties for stable options references:
export default {
data() {
return { rawData: [] }
},
computed: {
options() {
return this.rawData.map(item => ({
label: item.name,
value: item.id,
category: item.category
}))
}
}
}
Avoiding Common Pitfalls
Problem: Mutating options array in place doesn't trigger updates.
// Problematic - Vue might not detect this change
this.options.push(newOption)
// Solution - Create new array reference
this.options = [...this.options, newOption]
Problem: Reduced values with no matching option don't display correctly.
Ensure initial values correspond to options that reduce to matching values. Always test your reduce configuration with the data types you're storing.
Performance Tips
- Use debounced search for large option sets (1000+ items)
- Consider server-side filtering for very large datasets
- Implement proper caching for API-loaded options
- Use resetOnOptionsChange for controlled selection reset behavior
For comprehensive performance guidance, consult the Vue Select performance considerations in the official documentation.
Building efficient Vue.js applications requires attention to component performance across your entire stack. Proper error handling in Node.js applications complements Vue Select implementations by ensuring robust error management throughout your full-stack application. Our web development services can help you optimize your Vue applications for scale and performance.
Frequently Asked Questions
How do I set a default selected value in Vue Select?
Set the v-model to the value you want pre-selected. For object arrays without reduce, provide the full option object. With reduce, provide the reduced value that corresponds to an option.
Can I use Vue Select with TypeScript?
Yes, vue-select includes TypeScript definitions. Import the component and use standard Vue 3 with TypeScript patterns. The package exports proper type definitions for all props and events. For a deeper comparison of TypeScript versus JSDoc approaches, see our guide on [TypeScript vs JSDoc for JavaScript](/resources/guides/web-development/typescript-vs-jsdoc-javascript/).
How do I customize the appearance of Vue Select?
Vue Select uses scoped CSS variables you can override in your stylesheet. For deeper customization, use the components prop to replace internal components like the dropdown toggle or selected tag display with your own implementations.
How do I handle async options loaded from an API?
Load options in your component (via onMounted or a watcher), then pass them to the options prop. Use the loading prop to show a spinner while fetching, and consider implementing debounced search for large datasets.
Can I use Vue Select with Vuex or Pinia?
Yes. Bind :value to your store state and use @input to dispatch actions that update state, rather than v-model for direct mutation. This maintains unidirectional data flow compatible with state management patterns.