What is vue-multiselect?
vue-multiselect is a powerful and flexible Vue.js component for creating dropdowns with multi-select capabilities. It supports single and multiple selections, tagging, filtering, and custom rendering of options.
What are vue-multiselect's main functionalities?
Single Select
This feature allows users to select a single option from a dropdown list. The `multiple` prop is set to `false` to enable single selection.
<template>
<multiselect v-model="selected" :options="options" :multiple="false"></multiselect>
</template>
<script>
import Multiselect from 'vue-multiselect';
export default {
components: { Multiselect },
data() {
return {
selected: null,
options: ['Option 1', 'Option 2', 'Option 3']
};
}
};
</script>
Multiple Select
This feature allows users to select multiple options from a dropdown list. The `multiple` prop is set to `true` to enable multiple selections.
<template>
<multiselect v-model="selected" :options="options" :multiple="true"></multiselect>
</template>
<script>
import Multiselect from 'vue-multiselect';
export default {
components: { Multiselect },
data() {
return {
selected: [],
options: ['Option 1', 'Option 2', 'Option 3']
};
}
};
</script>
Tagging
This feature allows users to add new options (tags) to the dropdown list. The `taggable` prop is set to `true`, and the `@tag` event is used to handle the addition of new tags.
<template>
<multiselect v-model="selected" :options="options" :taggable="true" @tag="addTag"></multiselect>
</template>
<script>
import Multiselect from 'vue-multiselect';
export default {
components: { Multiselect },
data() {
return {
selected: [],
options: ['Option 1', 'Option 2', 'Option 3']
};
},
methods: {
addTag(newTag) {
this.options.push(newTag);
this.selected.push(newTag);
}
}
};
</script>
Custom Option Rendering
This feature allows users to customize the rendering of options in the dropdown list. The `custom-label` prop is used to define a method that returns a custom label for each option.
<template>
<multiselect v-model="selected" :options="options" :custom-label="customLabel"></multiselect>
</template>
<script>
import Multiselect from 'vue-multiselect';
export default {
components: { Multiselect },
data() {
return {
selected: null,
options: [
{ name: 'Option 1', id: 1 },
{ name: 'Option 2', id: 2 },
{ name: 'Option 3', id: 3 }
]
};
},
methods: {
customLabel(option) {
return `${option.name} (ID: ${option.id})`;
}
}
};
</script>
Other packages similar to vue-multiselect
vue-select
vue-select is a Vue.js component that provides a similar set of features to vue-multiselect, including single and multiple selections, tagging, and custom option rendering. It is known for its simplicity and ease of use.
vue-multiselect-next
vue-multiselect-next is a fork of vue-multiselect that aims to provide additional features and improvements. It offers similar functionalities with enhanced performance and additional customization options.
vue-treeselect
vue-treeselect is a multi-select component with nested options support. It is particularly useful for hierarchical data structures and provides features like single and multiple selections, search, and custom rendering.
vue-multiselect
Probably the most complete selecting solution for Vue.js 2.0, without jQuery.
Features & characteristics:
- NO dependencies
- Single select
- Multiple select
- Tagging
- Dropdowns
- Filtering
- Search with suggestions
- Logic split into mixins
- Basic component and support for custom components
- V-model support
- Vuex support
- Async options support
- > 99% test coverage
- Fully configurable (see props list below)
Breaking changes:
- Instead of Vue.partial for custom option templates you can use a custom render function.
- The
:key
props has changed to :track-by
, due to conflicts with Vue 2.0. - Support for
v-model
@update
has changed to @input
to also work with v-model:selected
has changed to :value
for the same reason- Browserify users: if you wish to import
.vue
files, please add vueify
transform.
Install & basic usage
npm install vue-multiselect@next
<template>
<div>
<multiselect
v-model="selected"
:options="options">
</multiselect>
</div>
</template>
<script>
import Multiselect from 'vue-multiselect'
export default {
components: { Multiselect },
data () {
return {
selected: null,
options: ['list', 'of', 'options']
}
}
}
</script>
<style src="vue-multiselect/dist/vue-multiselect.min.css"></style>
Roadmap:
Examples
in jade-lang/pug-lang
Single select / dropdown
multiselect(
:value="value",
:options="source",
:searchable="false",
:close-on-select="false",
:allow-empty="false",
@input="updateSelected",
label="name",
placeholder="Select one",
track-by="name"
)
Single select with search
multiselect(
v-model="value",
:options="source",
:close-on-select="true",
:clear-on-select="false",
placeholder="Select one",
label="name",
track-by="name"
)
Multiple select with search
multiselect(
v-model="multiValue",
:options="source",
:multiple="true",
:close-on-select="true",
placeholder="Pick some",
label="name",
track-by="name"
)
Tagging
with @tag
event
multiselect(
v-model="taggingSelected",
:options="taggingOptions",
:multiple="true",
:taggable="true",
@tag="addTag",
tag-placeholder="Add this as new tag",
placeholder="Type to search or add tag",
label="name",
track-by="code"
)
addTag (newTag) {
const tag = {
name: newTag,
code: newTag.substring(0, 2) + Math.floor((Math.random() * 10000000))
}
this.taggingOptions.push(tag)
this.taggingSelected.push(tag)
},
Asynchronous dropdown
multiselect(
v-model="selectedCountries",
:options="countries",
:multiple="multiple",
:searchable="searchable",
@search-change="asyncFind",
placeholder="Type to search",
label="name"
track-by="code"
)
span(slot="noResult").
Oops! No elements found. Consider changing the search query.
methods: {
asyncFind (query) {
this.countries = findService(query)
}
}
Props config
props: {
options: {
type: Array,
required: true
},
multiple: {
type: Boolean,
default: false
},
value: {},
track-by: {
type: String,
default: false
},
label: {
type: String,
default: false
},
searchable: {
type: Boolean,
default: true
},
clearOnSelect: {
type: Boolean,
default: true
},
hideSelected: {
type: Boolean,
default: false
},
placeholder: {
type: String,
default: 'Select option'
},
maxHeight: {
type: Number,
default: 300
},
allowEmpty: {
type: Boolean,
default: true
},
resetAfter: {
type: Boolean,
default: false
},
closeOnSelect: {
type: Boolean,
default: true
},
customLabel: {
type: Function,
default: false
},
taggable: {
type: Boolean,
default: false
},
tagPlaceholder: {
type: String,
default: 'Press enter to create a tag'
},
max: {
type: Number,
default: false
},
id: {
default: null
},
optionsLimit: {
type: Number,
default: 1000
}
}
props: {
showPointer: {
type: Boolean,
default: true
}
},
props: {
selectLabel: {
type: String,
default: 'Press enter to select'
},
selectedLabel: {
type: String,
default: 'Selected'
},
deselectLabel: {
type: String,
default: 'Press enter to remove'
},
showLabels: {
type: Boolean,
default: true
},
limit: {
type: Number,
default: 99999
},
limitText: {
type: Function,
default: count => `and ${count} more`
},
loading: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false
}
}
Contributing
npm run dev
npm run bundle
npm run docs
npm run test
npm run unit-watch
For detailed explanation on how things work, checkout the guide and docs for vue-loader.