Vue Multiselect Component
Vue Multiselect is a versatile, dependency-free multiselect and tagging component designed for Vue 3 applications. Currently at version 3.5.0, it offers a wide range of features including single and multiple selection, tagging capabilities, filtering, search with suggestions, and asynchronous option loading. The library maintains a steady release cadence with frequent bug fixes and minor feature enhancements, as seen in its recent 3.x releases. A key differentiator is its minimal footprint and explicit lack of external runtime dependencies, making it a lightweight choice. It supports Vue's `v-model`, Vuex integration, and fully configurable props for extensive customization. The component ships with TypeScript types, ensuring a robust developer experience for TypeScript users.
Common errors
-
Cannot read properties of null (reading 'blur')
cause This error, often `null.blur()`, indicates an attempt to call the `blur` method on a null or undefined element, typically in specific interaction scenarios.fixThis was addressed in v2.1.8 and subsequently in v3.0.0-beta.3 and later stable v3 releases. Ensure you are on a recent stable version of `vue-multiselect` (v3.0.0 or higher) to avoid this issue. -
CSS styles for multiselect dropdown are incorrect or not applying as expected after update.
cause This is likely due to the dropdown's DOM element being 'teleported' to the end of the `body` starting from v3.3.0, changing its position relative to other elements and affecting CSS selectors.fixUpdate your CSS to target the multiselect dropdown element correctly, considering it might now be a direct child of `body`. Alternatively, set the `teleport` prop to `false` (available since v3.3.1) or specify a custom `teleportTarget` to keep the dropdown within the component's original DOM structure.
Warnings
- breaking In v3.3.0, the open multiselect dropdown's DOM element began being 'teleported' to the end of the `body`. This change might break existing CSS styling that relies on the dropdown's original position within the DOM tree.
- gotcha Vue Multiselect requires Vue's Options API to function correctly. Some versions of `@vitejs/plugin-vue` (specifically v5.2.2 and later) are known to potentially disable the Options API, leading to runtime issues.
- breaking Version 3.0.0 introduced full compatibility with Vue 3. While efforts were made to maintain backward compatibility with v2.x logic, direct upgrades from v2.x may require minor tweaks due to underlying Vue 3 specific changes.
- gotcha The `teleport` feature introduced in v3.3.0, which moved the dropdown to the end of the `body`, was made optional via a prop in v3.3.1. If you upgraded to v3.3.0 and experienced broken styling, later reverting to v3.3.1+ might require explicit `teleport` prop configuration.
Install
-
npm install vue-multiselect -
yarn add vue-multiselect -
pnpm add vue-multiselect
Imports
- VueMultiselect
import { VueMultiselect } from 'vue-multiselect'import VueMultiselect from 'vue-multiselect'
- CSS Styles
import 'vue-multiselect/dist/vue-multiselect.min.css'
import 'vue-multiselect/dist/vue-multiselect.css'
- Type (MultiselectOption)
import type { MultiselectOption } from 'vue-multiselect'
Quickstart
<template>
<div>
<VueMultiselect
v-model="selectedItem"
:options="availableOptions"
:multiple="true"
:taggable="true"
@tag="addOptionTag"
tag-placeholder="Add as new tag"
placeholder="Type to search or add tag"
label="name"
track-by="code">
</VueMultiselect>
<p>Selected: {{ selectedItem }}</p>
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
import VueMultiselect from 'vue-multiselect';
import 'vue-multiselect/dist/vue-multiselect.css';
interface Option {
name: string;
code: string;
}
export default defineComponent({
components: { VueMultiselect },
setup() {
const selectedItem = ref<Option[]>([
{ name: 'Apple', code: 'AP' }
]);
const availableOptions = ref<Option[]>([
{ name: 'Apple', code: 'AP' },
{ name: 'Banana', code: 'BN' },
{ name: 'Cherry', code: 'CH' }
]);
const addOptionTag = (newTag: string) => {
const tag: Option = {
name: newTag,
code: newTag.substring(0, 2).toUpperCase() + Math.floor(Math.random() * 10000000)
};
availableOptions.value.push(tag);
selectedItem.value.push(tag);
};
return {
selectedItem,
availableOptions,
addOptionTag
};
}
});
</script>
<style>
/* Optional: Adjust global styles if needed */
</style>