next-select is a Vue.js component to provides a complete select box solution for Vue.js 3+ applications.
Features live filtering, dynamic options rendering, multi-select, tagging input, and much more.
1. Import the next-select.
import { reactive, ref, createApp } from 'vue'
import VueSelect from 'vue-next-select'
import 'vue-next-select/dist/index.min.css'
2. Create a single select box.
const { ref, createApp } = Vue
const singleSelect = createApp({
name: 'app',
setup() {
const model = ref(null)
const options = ref([
'Select option',
'Option',
'Mulitple',
'Searchable',
'Taggable',
'Close on select',
'Hide selected',
])
return {
model,
options,
}
},
template: `
<vue-select
v-model="model"
:options="options"
close-on-select
:min="1"
></vue-select>
<pre>{{ model || 'null' }}</pre>
`,
})
singleSelect.component('vue-select', VueNextSelect)
singleSelect.mount(document.querySelector('#single-select'))
3. Create a multi-select box.
const { ref, computed, createApp } = Vue
const app = createApp({
name: 'app',
setup() {
const options = ref([
{ name: 'Vue.js', language: 'JavaScript' },
{ name: 'Rails', language: 'Ruby' },
{ name: 'Sinatra', language: 'Ruby' },
{ name: 'Laravel', language: 'PHP' },
{ name: 'Phoenix', language: 'Elixir' },
])
const model = ref(['Sinatra', 'Vue.js'])
return {
model,
options,
}
},
template: `
<vue-select
v-model="model"
:options="options"
multiple
label-by="name"
track-by="name"
value-by="name"
:max="2"
placeholder="Pick some"
></vue-select>
<pre>{{ model }}</pre>
`,
})
app.component('vue-select', VueNextSelect)
app.mount(document.querySelector('#multiple-select'))
4. Enable the live search functionality on the select box.
const { ref, computed, createApp } = Vue
const app = createApp({
name: 'app',
setup() {
const options = ref([
{ name: 'Vue.js', language: 'JavaScript' },
{ name: 'Rails', language: 'Ruby' },
{ name: 'Sinatra', language: 'Ruby' },
{ name: 'Laravel', language: 'PHP' },
{ name: 'Phoenix', language: 'Elixir' },
])
const model = ref(options.value[0])
const searchInput = ref('')
const hanldeSearchInput = event => {
searchInput.value = event.target.value
}
const visibleOptions = computed(() => {
const re = new RegExp(searchInput.value)
return options.value.filter(option => re.test(option.name))
})
return {
model,
options,
hanldeSearchInput,
visibleOptions,
}
},
template: `
<vue-select
v-model="model"
:options="options"
:visible-options="visibleOptions"
label-by="name"
track-by="name"
searchable
clear-on-select
@search-input="hanldeSearchInput"
></vue-select>
<pre>{{ model || 'null' }}</pre>
`,
})
app.component('vue-select', VueNextSelect)
app.mount(document.querySelector('#select-with-search'))
5. Create a tag input.
const getCountryList = async name => {
return new Promise(resolve => {
const xhr = new XMLHttpRequest()
xhr.open('GET', `https://restcountries.eu/rest/v2/name/${name}`)
xhr.send()
xhr.onloadend = () => {
try {
resolve(JSON.parse(xhr.response).map(info => info.name))
} catch (error) {
resolve([])
}
}
})
}
const { ref, createApp } = Vue
const app = createApp({
name: 'app',
setup() {
const options = ref([
{ name: 'Vue.js', language: 'JavaScript' },
{ name: 'Rails', language: 'Ruby' },
{ name: 'Sinatra', language: 'Ruby' },
{ name: 'Laravel', language: 'PHP' },
{ name: 'Phoenix', language: 'Elixir' },
])
const model = ref(['Vue.js', 'Rails', 'Phoenix'])
return {
model,
options,
}
},
template: `
<vue-select
v-model="model"
:options="options"
multiple
taggable
hide-selected
label-by="name"
track-by="name"
value-by="name"
collapse-tags
></vue-select>
<pre>{{ model }}</pre>
`,
})
app.component('vue-select', VueNextSelect)
app.mount(document.querySelector('#tagging'))
6. Create an asynchronous select.
const getCountryList = async name => {
return new Promise(resolve => {
const xhr = new XMLHttpRequest()
xhr.open('GET', `https://restcountries.eu/rest/v2/name/${name}`)
xhr.send()
xhr.onloadend = () => {
try {
resolve(JSON.parse(xhr.response).map(info => info.name))
} catch (error) {
resolve([])
}
}
})
}
const { ref, createApp } = Vue
const app = createApp({
name: 'app',
setup() {
const options = ref([])
const visibleOptions = ref([])
const model = ref([])
const loadingCount = ref(0)
const searchInput = ref('')
const handleSearchInput = async event => {
searchInput.value = event.target.value
if (searchInput.value === '') {
visibleOptions.value = model.value
return
}
++loadingCount.value
const currentSearchInput = searchInput.value
const foundOptions = await getCountryList(searchInput.value)
if (currentSearchInput === searchInput.value) {
options.value = model.value.concat(foundOptions)
options.value = Array.from(new Set(options.value))
visibleOptions.value = foundOptions
}
--loadingCount.value
}
return {
model,
options,
visibleOptions,
loadingCount,
handleSearchInput,
}
},
template: `
<vue-select
v-model="model"
:options="options"
:visible-options="visibleOptions"
multiple
taggable
searchable
:min="3"
@search-input="handleSearchInput"
:loading="loadingCount !== 0"
></vue-select>
<pre>{{ model }}</pre>
`,
})
app.component('vue-select', VueNextSelect)
app.mount(document.querySelector('#asynchronous-select'))
Author: iendeavor
Demo: https://iendeavor.github.io/vue-next-select/
Source Code: https://github.com/iendeavor/vue-next-select
#vue #vuejs #javascript