vuejs-tips / v-debounce Goto Github PK
View Code? Open in Web Editor NEWInput debounce directive for Vue.js
Home Page: https://vuejs-tips.github.io/v-debounce/
Input debounce directive for Vue.js
Home Page: https://vuejs-tips.github.io/v-debounce/
Add the below to /plugins/debounce-directive.js
Then include in nuxt.config.js:
plugins: ['~/plugins/debounce-directive.js']
Finally use as suggested (v-model.lazy):
<input v-model.lazy="sample" v-debounce="delay" />
// plugins/debounce-directive.js
function debounce(fn, delay) {
let timeoutID = null;
return function (...args) {
clearTimeout(timeoutID);
timeoutID = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
}
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.directive('debounce', {
mounted(el, binding) {
if (el.tagName.toLocaleUpperCase() !== 'INPUT') {
console.warn('v-debounce directive is intended for use with <input> elements and v-model.lazy.');
return;
}
const debounceFunction = debounce(() => {
// Create and dispatch the 'change' event to trigger v-model.lazy update
const event = new Event('change', { bubbles: true });
el.dispatchEvent(event);
}, parseInt(binding.value, 10) || 500); // Use the directive's value as the debounce delay
el.addEventListener('input', (event) => {
event.stopImmediatePropagation(); // Prevent immediate propagation to allow for debouncing
// Call the debounce function which will emit the 'change' event after delay
debounceFunction();
}, true);
},
beforeUnmount(el) {
// Clean up if necessary
el.removeEventListener('input', el.oninput);
}
});
});
Try this one, which doesn't work:
<input @input="method()" v-debounce="400" :value="someValue">
This one works:
<input @changed="method()" v-debounce="400" :value="someValue">
I can't use v-model since I'm using the value as prop.
Note: I need @input
event since @changed
is broken (invoked on many cases).
Please consider the following example:
https://codesandbox.io/s/vdebounce-input-override-ej4nz
Greatly simplified from a large application using observables to fetch filtered data from an API.
I've mocked the API response with a random timeout. The behavior of the input is very similar to what I get in the app.
When the responses come in, the input loses a 1 or 2 letters if you're typing.
If I drop the v-debounce
or the .lazy
modifier, input works fine but there's no debounce.
Is there a fix for this or do I have to use a different debounce
wrapper (i.e: lodash
) inside the watcher and dump v-debounce
altogether?
Thank you.
Note: I also created the v-debounce tag on StackOverflow.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.