We have been busy using Vuetify for a new project and wanted to improve the selection of a person from a very long list. To avoid loading the entire list every time we wanted to use our API. Returning only a subset of people based on the user’s input. Additionally we wanted to avoid firing this on every key stroke, but rather every time the user paused their input.
We were able to achieve this using v-autocomplete. However the documentation for this use case was lacking, incomplete or just confusing. Below is our implementation using v-autocomplete.
We decided to use the debounce library to handle the timing of when to fire the search to the API. Debounce works by postponing the execution of a given function until after a given amount of milliseconds have elapsed. This resets every time the function is invoked.
Before reading the below code, it is worth noting that we use vue-api-query but you could easily replace this with your out preferred AJAX methods. Also you may have to tweak v-autocomplete item-text=”name”
item-value=”id” options to suit your data.
<template> <v-layout align-center justify-center row> ... <v-autocomplete v-model="person" :items="personOptions" :loading="loadingPersons" :search-input.sync="search" hide-no-data item-text="name" item-value="id" label="Person" prepend-icon="person" append-icon="" placeholder="Start typing to Search" clearable return-object ></v-autocomplete> ... </v-layout> </template> <script>
// We use https://github.com/robsontenorio/vue-api-query
// and create a custom model import Person from '@/model/Person' import debounce from 'debounce' export default { data() { return { person: null, personOptions: [], search: '', loadingPersons: false, } }, methods: { makeSearch: async (value, self) => { // Handle empty value if (!value) { self.personOptions = []; self.person = ''; } // Items have already been requested if (self.loadingPerson) { return } self.loadingPerson = true
// YOUR AJAX Methods go here
// if you prefer not to use vue-api-query await Person .where('name', value) .get() .then(response => { self.personOptions = response.data }).catch(error => { self.error = 'Unknown Error. Please check details and try again.' self.failed() }) .finally(() => (self.loadingLearner = false)) } }, watch: { search(value) { if (!value) { return }
// Debounce the input and wait for a pause of at
// least 200 milliseconds. This can be changed to
// suit your needs. debounce(this.makeSearch, 200)(value, this) } } } </script>
Comments are closed.