Vue 3 multiselect by @vueform

Vue 3 multiselect component with single select, multiselect and tagging options.

Features

  • Vue 2 & 3 support
  • No dependencies
  • Lightweight (~4.5 kB gzipped)
  • 100% coverage
  • ESM support
  • Single select options
  • Multiple select options
  • Tags
  • Search & filtering
  • Custom slots
  • Events
  • Fully configurable

Installation

npm install @vueform/multiselect

Usage with Vue 3

<template>
  <div>
    <Multiselect
      v-model="value"
      :options="options"
    />
  </div>
</template>

<script>
  import Multiselect from '@vueform/multiselect'

  export default {
    components: {
      Multiselect,
    },
    data() {
      return {
        value: null,
        options: [
          'Batman',
          'Robin',
          'Joker',
        ]
      }
    }
  }
</script>

<style src="@vueform/multiselect/themes/default.css"></style>

Usage with Vue 2

When using with Vue 2 make sure to install @vue/composition-api first and change the imported module to:

import Multiselect from '@vueform/multiselect/dist/multiselect.vue2.js'

Props

Name Type Default Description
appendNewTag boolean true Whether should append new tag automatically to multiselect's options when using tags mode with createTag. If set to false you need to take care of appending a new tag to the :options list upon @tag event.
caret boolean true Whether should display a caret (small triangle on the right).
createTag boolean false Whether should allow creating new tag based on search query when using tags mode.
disabled boolean false Whether the input should be disabled.
hideSelectedTag boolean true Whether selected tags should be excluded from the list when using tags mode.
id string 'multiselect' The id of the multiselect container DOM.
label string 'label' If you provide an array of objects as options this property of those objects will be displayed for options and selected label.
limit number -1 The maximum number of options that should be displayed. If -1 it won't be limited.
loading boolean false Whether a loading spinner should be shown.
maxHeight number 160 The maximum height of options list.
mode string single Possible values: single\|multiple\|tags.
modelValue string\|number\|array null The variable that should store the select value when using Vue 3. If v-model is used it does not need to be set.
multipleLabel function A function that should return how the label should be displayed when using multiple mode. It receives value as an argument. By default it renders 1 option selected and [n] options selected based on value length.
noOptionsText string 'The list is empty' The text that should be displayed when options list is empty.
noResultsText string No results found The text that should be when there are no search results.
object boolean false Whether the value should be stored as an object. If set to false while using an array of objects as :options the value property will be used as value. If set to true without using an array of objects as :options an object that contains value property along with :trackBy's and :label's value will be set as value.
options array\|object [] List of options. Can be:
- an array (eg. [1,2,3])
- an object (eg. {a:1,b:2,c:3})
- an array of objects [{value:1,label:'v1'},{value:2,label:'v2'},{value:3,label:'v3'}].
When an array of objects is provided it must have a value property as well as properties that equal to :trackBy's and :label's value (both configurable and default to label).
placeholder string null The text that should be displayed before an options are selected.
searchable boolean false Whether the options should be searchable.
trackBy string label The name of the property that should be searched when searchable is true and an array of objects are provided as :options.
value string\|number\|array null The variable that should store the select value when using Vue 2. If v-model is used it does not need to be set.

Events

Event Attributes Description
@close Emitted after closing the option list.
@deselect option Emitted after an option is deselected or a tag is removed.
@input value Emitted after the value is changed.
@open Emitted after opening the option list.
@search-change query Emitted after a character is typed.
@select option Emitted after an option or tag is selected.
@tag query Emitted after enter is hit when a new tag is being created.

Slots

Slot Attributes Description
afterList Rendered after the options list.
beforeList Rendered before the options list.
multipleLabel values Rendered when using multiple mode and options are selected. By default it renders the return value of multipleLabel function.
noOptions Rendered when the options list is empty. By default renders noOptionsText.
noResults Rendered when there are no search results. By default renders noResultsText.
option option, search Renders an option in options list.
singleLabel value Rendered when using single mode and an option is selected. By default it renders the :label if the selected option.
tag option, remove, disabled Renders a tag when using tags mode. When disabled the remove icon should not be displayed. The remove prop should be used to trigger the removal of the tag.

Examples

Single select with array options

<template>
  <div>
    <Multiselect
      v-model="value"
      placeholder="Select your character"
      :options="options"
    />
  </div>
</template>

<script>
  import Multiselect from '@vueform/multiselect'

  export default {
    components: { Multiselect },
    data() {
      return {
        value: null,
        options: ['Batman', 'Robin', 'Joker']
      }
    }
  }
</script>

<style src="@vueform/multiselect/themes/default.css"></style>

Single select with object options

<template>
  <div>
    <Multiselect
      v-model="value"
      placeholder="Select your character"
      :options="options"
    />
  </div>
</template>

<script>
  import Multiselect from '@vueform/multiselect'

  export default {
    components: { Multiselect },
    data() {
      return {
        value: null,
        options: {
          batman: 'Batman',
          robin: 'Robin',
          joker: 'Joker'
        }
      }
    }
  }
</script>

<style src="@vueform/multiselect/themes/default.css"></style>

Single select with custom options

<template>
  <div>
    <Multiselect
      v-model="value"
      placeholder="Select your character"
      label="name"
      trackBy="name"
      :options="options"
      :searchable="true"
    >
      <template v-slot:singleLabel="{ value }">
        <div class="multiselect-single-label">
          <img height="26" style="margin: 0 6px 0 0;" :src="value.icon"> {{ value.name }}
        </div>
      </template>

      <template v-slot:option="{ option }">
        <img height="22" style="margin: 0 6px 0 0;" :src="option.icon">{{ option.name }}
      </template>
    </Multiselect>
  </div>
</template>

<script>
  import Multiselect from '@vueform/multiselect'

  export default {
    components: { Multiselect },
    data() {
      return {
        value: null,
        options: [
          { value: 'captainamerica', name: 'Captain America', icon: 'https://cdn2.iconfinder.com/data/icons/avengers-filled/48/03_-_Captain_America_-_infinity_war_-_end_game_-_marvel_-_avengers_-_super_hero-512.png' },
          { value: 'spiderman', name: 'Spiderman', icon: 'https://cdn2.iconfinder.com/data/icons/avengers-filled/48/12_-_Spiderman_-_infinity_war_-_end_game_-_marvel_-_avengers_-_super_hero-512.png' },
          { value: 'ironman', name: 'Iron Man', icon: 'https://cdn2.iconfinder.com/data/icons/avengers-filled/48/02_-_IRONMAN_-_infinity_war_-_end_game_-_marvel_-_avengers_-_super_hero-512.png' },
        ]
      }
    }
  }
</script>

<style src="@vueform/multiselect/themes/default.css"></style>

Multiselect

<template>
  <div>
    <Multiselect
      v-model="value"
      mode="multiple"
      placeholder="Select your characters"
      :options="options"
    />
  </div>
</template>

<script>
  import Multiselect from '@vueform/multiselect'

  export default {
    components: { Multiselect },
    data() {
      return {
        value: [],
        options: ['Batman', 'Robin', 'Joker']
      }
    }
  }
</script>

<style src="@vueform/multiselect/themes/default.css"></style>

Multiselect with custom label

<template>
  <div>
    <Multiselect
      v-model="value"
      mode="multiple"
      placeholder="Select your characters"
      :options="options"
    >
      <template v-slot:multipleLabel="{ values }">
        <div class="multiselect-multiple-label">
          {{ values.length }} characters selected
        </div>
      </template>
    </Multiselect>
  </div>
</template>

<script>
  import Multiselect from '@vueform/multiselect'

  export default {
    components: { Multiselect },
    data() {
      return {
        value: [],
        options: ['Batman', 'Robin', 'Joker']
      }
    }
  }
</script>

<style src="@vueform/multiselect/themes/default.css"></style>

Tags with search

<template>
  <div>
    <Multiselect
      v-model="value"
      mode="tags"
      placeholder="Select your characters"
      :options="options"
      :search="true"
    />
  </div>
</template>

<script>
  import Multiselect from '@vueform/multiselect'

  export default {
    components: { Multiselect },
    data() {
      return {
        value: [],
        options: ['Batman', 'Robin', 'Joker']
      }
    }
  }
</script>

<style src="@vueform/multiselect/themes/default.css"></style>

Tags with create option

<template>
  <div>
    <Multiselect
      v-model="value"
      mode="tags"
      placeholder="Select your characters"
      :options="options"
      :searchable="true"
      :createTag="true"
    />
  </div>
</template>

<script>
  import Multiselect from '@vueform/multiselect'

  export default {
    components: { Multiselect },
    data() {
      return {
        value: [],
        options: ['Batman', 'Robin', 'Joker']
      }
    }
  }
</script>

<style src="@vueform/multiselect/themes/default.css"></style>

GitHub