個人の備忘録です。
環境
- vue: 2.7.x(Composition API / script setup)
- vuetify: 2.6.x
実現したいこと
- Vutify の v-autocomplete の検索クエリに基づいて API でデータを取得
- 0.5秒後に入力された値のみでデータを取得
困った点
- @update:search-input(search-input.sync)では、keydown 毎にイベントが発火してしまい、何度も API が走ってしまう。
変更前
<script setup lang="ts">
省略
interface State {
value: string;
isSearching: boolean;
users: Response[];
}
const state: State = reactive({
value: '',
isSearching: false,
users: [],
});
const onSearchInput = async (searchName: string) => {
state.isSearching = true;
state.users = await repository.getUsers(searchName);
state.isSearching = false;
};
</script>
<template>
<v-autocomplete
v-model="state.value"
:items="state.users"
// ここが keydown 毎に発火してしまう
@update:search-input="onSearchInput"
:loading="state.isSearching"
>
</v-autocomplete>
</template>
解決コード
- JavaScritp の clearTimeout で古いタイムアウトを解除する
変更後
<script setup lang="ts">
省略
interface State {
value: string;
isSearching: boolean;
users: Response[];
timerId?: ReturnType<typeof setTimeout>;
}
const state: State = reactive({
value: '',
isSearching: false,
users: [],
timerId: undefined,
});
const onSearchInput = (searchName: string) => {
state.isSearching = true;
// 古いタイムアウトは解除する
clearTimeout(state.timerId);
// 0.5秒後に発火する
state.timerId = setTimeout(async () => {
state.users = await repository.getUsers(searchName);
state.isSearching = false;
}, 500);
};
</script>
<template>
<v-autocomplete
v-model="state.value"
:items="state.users"
@update:search-input="onSearchInput"
:loading="state.isSearching"
>
</v-autocomplete>
</template>
参照