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.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs