To make dropdowns easier, we can use the Vue Select plugin to add the dropdown.
It can do much more than the select element.
In this article, we’ll look at how to use the vue-select package to make more complex dropdowns.
Loading Options with Ajax
We can load options with Ajax.
For example, we can write:
<template>
<v-select @search="fetchOptions" :options="options"/>
</template>
<script>
export default {
data() {
return {
allOptions: ["apple", "orange", "grape"],
options: []
};
},
methods: {
fetchOptions(search, loading) {
setTimeout(() => {
this.options = this.allOptions.filter(a =>
a.toLowerCase().includes(search.toLowerCase())
);
}, 1000);
}
}
};
</script>
to add the fetchOptions
method and set it as the listener of the search
event.
The search
parameter has our search query.
loading
lets us toggle the loading state.
Then we set the options
prop to the options
state.
Disabling Filtering
We can disable client-side filtering when we’re loading the options from the server-side.
To do that, we set the filterable
prop to false
:
<template>
<v-select @search="fetchOptions" :options="options" :filterable="false"/>
</template>
<script>
export default {
data() {
return {
allOptions: ["apple", "orange", "grape"],
options: []
};
},
methods: {
fetchOptions(search, loading) {
setTimeout(() => {
this.options = this.allOptions.filter(a =>
a.toLowerCase().includes(search.toLowerCase())
);
}, 1000);
}
}
};
</script>
Loading Spinner
We can add a spinner by populating the spinner
slot:
<template>
<v-select @search="fetchOptions" :options="options" :filterable="false">
<template v-slot:spinner="{ loading }">
<div v-show="loading">Loading...</div>
</template>
</v-select>
</template>
<script>
export default {
data() {
return {
allOptions: ["apple", "orange", "grape"],
options: []
};
},
methods: {
fetchOptions(search, loading) {
loading(true);
setTimeout(() => {
this.options = this.allOptions.filter(a =>
a.toLowerCase().includes(search.toLowerCase())
);
loading(false);
}, 2000);
}
}
};
</script>
loading
is a function that pass a boolean value to set the loading
class.
If we pass true
, then the loading
class is added.
Otherwise, it’s removed.
We put whatever we want to display as the loading indicator in the spinner
slot.
Now when we search for something, the Loading… text will be displayed.
Vue Select in v-for Loops
We can use Vue Select within loops.
For example, we can write:
<template>
<table>
<tr>
<th>Name</th>
<th>Country</th>
</tr>
<tr v-for="p in people" :key="p.name">
<td>{{ p.name }}</td>
<td>
<v-select
:options="options"
:value="p.country"
@input="country => updateCountry(p, country)"
/>
</td>
</tr>
</table>
</template>
<script>
export default {
data: () => ({
people: [{ name: "John", country: "" }, { name: "Jane", country: "" }],
options: ["Canada", "United States"]
}),
methods: {
updateCountry(person, country) {
person.country = country;
}
}
};
</script>
We created a table with rows created with v-for
.
The v-select
component has the dropdowns to add.
We set the dropdown choice for the entry by listening to the input
event.
It’ll be run when we select a choice with the dropdown.
Conclusion
We can load data from the server-side and show a loading indicator with the Vue-Select component.
The dropdowns can also be used in loops.