Home > Blockchain >  How dynamic update v-combobox items list?
How dynamic update v-combobox items list?

Time:01-04

I use v-combobox to search through the API, and I want to display hints in the drop-down list, the problem is that initially the array :items is empty, and when data comes from the API, the drop-down list does not open automatically, I have to repeatedly click on the input field to see the result

<script setup>
const inputValue = ref('')
const items = ref([])

watch(inputValue, async value => {
  const response = await fetch('...')
  items.value = await response.json()
})
</script>

<template>
  <v-combobox
    v-model="inputValue"
    :items="items"
  >   
  </v-combobox>
</template>

P.S: I could use v-textfield and v-menu, but then I won't be able to use the arrows on the keyboard to control the list.

CodePudding user response:

Solution

1. use <v-autocomplete /> instead of <v-combobox />

<v-autocomplete /> is more appropriate for this sort of operation, as stated in Vuetify official document:

Easily hook up dynamic data and create a unique experience. The v-autocomplete’s expansive prop list makes it easy to fine tune every aspect of the input.

(excerpt from v-combobox > API search)

2. trigger the query action from v-on:focus

<!- v-model:search and v-model are both present
  to preserve manual user input ->
<v-autocomplete
  v-model:search="keyword"
  v-model="select"
  :items="items"
  @focus="() => query(keyword)" />
// script
const query = async (_keyword: string) => {
  loading.value = true;
  const filteredLists = await fetchData(_keyword);
  items.value = filteredLists;
  loading.value = false;
};

full code

<template>
    <v-autocomplete
      v-model:search="keyword"
      v-model="select"
      :items="items"
      :loading="loading"
      @focus="() => query(keyword)"
    />
</template>

<script setup lang="ts">
import { ref, watch } from 'vue';
import { fetchData } from '@/lib/mockedApi';

const select = ref(null);
const keyword = ref('');
const items = ref<string[]>([]);
const loading = ref(false);
const query = async (_keyword: string) => {
  loading.value = true;
  const filteredLists = await fetchData(_keyword);
  items.value = filteredLists;
  loading.value = false;
};
watch(keyword, (v) => {
  query(v);
});
</script>

edit

I didn't use v-autocomplete because when the focus is lost, the value is reset there.

if the keyword(result) has to be independent of list value, just replace <v-autocomplete /> with <v-combobox />.

The demo also has been updated accordingly. It includes demo for both combobox and autocomplete.

<template>
    <v-combobox
      v-model:search="keyword"
      v-model="select"
      :items="items"
      :loading="loading"
      @focus="() => query(keyword)"
    />
</template>

working demo available on Github: https://github.com/rabelais88/stackoverflow-answers/tree/main/74980402-vuetify-autocomplete

  • Related