JAVASCRIPT
Implementing a Simple Debounce Utility for Input Fields in Vue 3
Optimize performance in Vue 3 applications by implementing a debounce utility for input fields, reducing excessive function calls on rapid user typing and improving responsiveness.
// utils/debounce.js
export function debounce(func, delay) {
let timeoutId;
return function(...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
func.apply(this, args);
}, delay);
};
}
// MyComponent.vue
<template>
<div>
<label for="search">Search (Debounced):</label>
<input type="text" id="search" v-model="searchText" @input="debouncedSearch">
<p>Searching for: {{ displaySearchText }}</p>
<p v-if="isSearching">Searching...</p>
<ul v-if="searchResults.length">
<li v-for="item in searchResults" :key="item">{{ item }}</li>
</ul>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import { debounce } from '@/utils/debounce'; // Adjust path as needed
const searchText = ref('');
const displaySearchText = ref('');
const searchResults = ref([]);
const isSearching = ref(false);
// Simulate an API call
const performSearch = async (query) => {
if (!query) {
searchResults.value = [];
isSearching.value = false;
displaySearchText.value = '';
return;
}
isSearching.value = true;
displaySearchText.value = query; // Update display immediately, but search debounced
console.log('Performing search for:', query);
// Simulate network delay
await new Promise(resolve => setTimeout(resolve, 500));
searchResults.value = [`Result for ${query} A`, `Result for ${query} B`];
isSearching.value = false;
};
// Debounce the performSearch function
const debouncedSearch = debounce(() => {
performSearch(searchText.value);
}, 300); // 300ms delay
// Initial search or clear if input is empty
onMounted(() => {
// Trigger initial debounce if there's any default value
if (searchText.value) {
debouncedSearch();
}
});
</script>
<style scoped>
div {
max-width: 500px;
margin: 20px auto;
padding: 20px;
border: 1px solid #eee;
border-radius: 8px;
background-color: #fff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
font-family: Arial, sans-serif;
}
label {
display: block;
margin-bottom: 8px;
font-weight: bold;
}
input[type="text"] {
width: calc(100% - 20px);
padding: 10px;
margin-bottom: 15px;
border: 1px solid #ddd;
border-radius: 4px;
}
p {
margin-bottom: 10px;
}
ul {
list-style: none;
padding: 0;
border-top: 1px solid #eee;
margin-top: 15px;
}
li {
padding: 8px 0;
border-bottom: 1px solid #eee;
}
li:last-child {
border-bottom: none;
}
</style>
How it works: This snippet provides a practical implementation of a debounce utility in Vue 3, crucial for optimizing performance in interactive input fields. The `debounce` function wraps another function (`performSearch`), delaying its execution until a specified `delay` has passed without any further calls. This prevents `performSearch` (e.g., an API call) from firing on every keystroke, significantly reducing server load and improving client-side responsiveness, especially for search bars or auto-save features. The `v-model` binding updates the `searchText` instantly, while `debouncedSearch` controls when the actual search logic runs.