Code Monkey home page Code Monkey logo

vue-debounce's Introduction

vue-debounce

npm Downloads

A simple to use directive for debounce solutions

It attaches itself to an event for actions

JavaScript Style Guide

Important

As of now vue2-debounce is published on npm, if you are using vue2 I highly recommend migrating to this package as this one is going to start focusing on vue3 from v5 onward. Consider vue2 support deprecated for this module.

Content

Features

  • Dynamic debouncing for input based requests
  • Easy to use, just place it into your vue instance and attach it to your inputs/components
  • Self regulating no need to worry about it, set it and forget it
  • Multiple time formats supported (miliseconds and seconds)
  • Enter key support to automatically fire the desired function when the user hits the enter key in the desired input (Can also be disabled)
  • Supports the ability to have multiple event listeners, and specify events at the element level

Installation

npm i vue-debounce

Modifiers

  • lock : Used to lock the debounce and prevent the enter key from triggering the function when pressed
    • Example: v-debounce:400ms.lock="cb"
  • unlock : Used to unlock the enter key on a debounced input, useful if you want to use the lock option and only want a few debounced inputs unlocked
  • fireonempty : Use to signify that when that specific input is emptied, you want the function to fire right away
  • cancelonempty : Use this to specify that when the input is emptied you DO NOT want your debounced function to trigger at all
  • trim : Boolean - Tells debounce to trim out white space using the String.prototype.trim() function

Options

  • lock : Boolean - This works the same way as the modifier does, however using the option will lock ALL of the debounced inputs within that vue instance, where as using the modifer only locks the one it's attached to
  • listenTo : String|Array - Allows you to set a custom event attached to an element like input for example
    • This is given to the addEventListener method attached to the element
  • defaultTime : String - Set the default timer for debounce directives that you don't give a time to
  • fireOnEmpty : Boolean - Tells debounce that if the input is empty, then fire the function immediately
  • trim : Boolean - Tells debounce to trim out white space using the String.prototype.trim() function

Option Defaults

{
  lock: false,
  listenTo: 'keyup',
  defaultTime: '300ms',
  fireOnEmpty: false,
  trim: false
}

CDN Support

You can use vue debounce via CDN like so: (It is recommended that you don't use @latest however)

<script src="https://unpkg.com/vue-debounce@latest/dist/vue-debounce.min.js">
<script>
  vueDebounce.vueDebounce({ lock: true })
</script>

Setup

With vue3 we simply need to import the new directive function vueDebounce this function takes in an object of options (found above)

Using vue-debounce Globally:

import vueDebounce from 'vue-debounce'
import { createApp } from 'vue';
import App from './App.vue';

const app = createApp(App)
app
  .directive('debounce', vueDebounce({ lock: true }))
  .mount('#app');

Using the setup API at the component level:

<script setup>
import vueDebounce from 'vue-debounce'

const vDebounce = vueDebounce({ lock: true })
</script>

Using vue-debounce at a component level using the option API:

import vueDebounce from 'vue-debounce'

export default {
  directives: {
    debounce: vueDebounce({ lock: true })
  }
}

Using Just Debounce

With Vue-debounce you're also able to just use the debouncing function.

Simply require the debounce file.

import { debounce } from 'vue-debounce'

The debounce function returns a function back which in turn is debounced, so you can set them up ahead of time:

const dFn = debounce(val => console.log('normal format', val), '400ms')

dFn(10) // => 'normal format' 10
// Or
debounce(val => console.log('just a number!'), 400)(10) // => 'just a number!' 10

Usage

Then attach a time:format to the directive, and set the value to the function you want to call and attach it to your input element

Example:

<input v-debounce:300ms="myFunc" type="text" />

If no wait timer is passed in, then the directive will default to whatever you set defaultTime to, OR 300ms if that isn't set.

You can pass the time in multiple formats:

<!-- If no time format is attached ms is used -->
<input v-debounce:300="myFunc" type="text" />

<!-- Seconds format is supported -->
<input v-debounce:1s="myFunc" type="text" />

The value of the input is passed along to your function as the first parameter, and the 2nd parameter is the event object itself.

Modifier Usage

Using modifiers works just like normal Vue directives. You can chain them to the timeout value and each other. Some examples include:

IMPORTANT NOTE: Modifiers WILL overwrite options you have set, for example if you set the fireOnEmpty option set to true and then tag a input with the cancelonempty modifier then the debounced function will cancel when THAT input is empty instead of fire.

<!-- Using Modifiers locking the input so the enter key isn't registered -->
<input v-debounce:1s.lock="myFunc" type="text" />

<!-- Using Modifiers unlocking the input so the enter key is registered -->
<!-- If you've set lock to true as an option when adding this module -->
<input v-debounce:1s.unlock="myFunc" type="text" />

<!-- Using the fireonempty modifier triggers your debounced function when this specific input field is empty -->
<input v-debounce:1s.fireonempty="myFunc" type="text" />

<!-- Using the cancelonempty modifier tells debounce to cancel function execution when the field is empty -->
<input v-debounce:1s.cancelonempty="myFunc" type="text" />

Overwriting Events

As of Version 1.2.0 you can assign specific event listeners to specific inputs. Doing so overwrites ANY of the listed events set with listenTo

Example:

// This can accept an array or a single string when using the bind `:` syntax
<input v-debounce:1s="myFunc" :debounce-events="['click', 'keydown']">
<input v-debounce:1s="myFunc" :debounce-events="'click'">

// You can also just use it as an attribute, though if passing multiple events binding it is preferred
<input v-debounce:1s="myfunc" debounce-events="click">

A full example:

<template>
  <input v-debounce:400ms="myFn" type="text" />
  <input v-debounce:400ms="myFn" debounce-events="click" type="text" />
</template>
<script>
export default {
  methods: {
    myFn(val, e) {
      console.log(val) // => The value of the input
      console.log(e) // => The event object
    }
  }
}
</script>

Typescript Support

While this project is not written in typescript, we do define types in the types directory. Unfortunately the way Vue is currently typed the only type support you will get is when you Vue.use(vueDebounce).

i.e.

import Vue from 'vue'
import vueDebounce, { PluginConfig, debounce } from 'vue-debounce'

debounce(() => console.log('just a number!'), 400)
debounce(() => console.log('normal format'), '400ms')

Vue.use<PluginConfig>(vueDebounce, { lock: true, defaultTime: '400ms', listenTo: 'keyup' })

Hopefully in the future Vue will allow directives to type the modifiers and values that are accepted.

Caveats

If a library you are using such as Vueftify is already using a specified event, it will block vue debounce from being able to listen to that event.

As of v3.1.0 I have significantly improved compatability with these kinds of libraries, however this problem still remains.

For example, Vuetify makes pretty heavy use of the onblur event for a lot of it's styles/animatons, so I'd recommend telling vue-debounce to listen for focusout instead, if you want debounce to trigger on a blur like event.

I will keep doing research into a better way to solve this little issue, but for now the improved compatability should help a lot!

vue-debounce's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

vue-debounce's Issues

How to use debouncing function inside watcher?

Right now I have a text entry box that I want to debounce, but when the text input is blank I want it to be sent instantly.

methods: {
      sendSearchValue () {
        this.$emit('input', this.search_text)
      }
    },
watch: {
      search_text (newVal) {
        if (newVal.length == 0) {
          this.$emit('input', '')
        } else {
          let vm = this
          console.log(`search_text ${newVal}, debouncing`)
          debounce(() => vm.sendSearchValue(), '400ms')
        }
      }
    },
<input type="text" 
v-model="search_text" 
ref="user_search"  
id="omnibar-search-field" 
v-on:keyup.enter="sendSearchValue"
/>

On my element I have it working just fine if I add v-debounce:300="sendSearchValue", but I feel like I am using the custom debounce function incorrectly. Is there something that I am missing?

trigger on Enter key only

Couldn't find a way to call the debounce function by pressing only the Enter Key (normal input behavior)
Basically what I would like to do is to remove the default event 'keyup' and get back the normal behavior of my input:

v-debounce:500="search" debounce-events=""

or to restrict it to only the Enter key (similar to the Key Modifiers of Vue)

v-debounce:500="search" :debounce-events="'keyup.enter'"

Type error "Could not find a declaration file for module 'vue-debounce'" in fresh vue3 typescript project

Describe the bug
Trying to use vue-debounce in a vue3 typescript project gives an error about type declarations.

Could not find a declaration file for module 'vue-debounce'. 'c:/src/rv-frontend/node_modules/vue-debounce/dist/vue-debounce.min.mjs' implicitly has an 'any' type.
  There are types at 'c:/src/rv-frontend/node_modules/vue-debounce/types/index.d.ts', but this result could not be resolved when respecting package.json "exports". The 'vue-debounce' library may need to update its package.json or typings.

Version of Vue
Error occurs in fresh install from create-vue 3.9.0. An example can be found here but the main versions of dependencies are

    "vue": "3.3.10",
    "vue-debounce": "4.0.1",
    "@vue/tsconfig": "0.4.0",
    "typescript": "5.2.0",
    "vite": "5.0.5",
    "vue-tsc": "1.8.25"

To Reproduce
Steps to reproduce the behavior:

  1. clone https://github.com/Zazcallabah/vue3-test
  2. npm install
  3. npm run type-check

Expected behavior
No errors in type check

Desktop (please complete the following information):

  • build error, browser not used

Does it works with Checkboxes?

Version of Vue
Which version of vue are you using?
Vue 2
Browser
What browser are you using?
Chrome

Works well with input text, but doesn't works with checkboxes.

<input type="checkbox" v-model="test" v-debounce:300ms="onInput">
My page has many of them and would be great if it can work with checkboxes as well, don't want to send data to API on every check.

CDN (like unpkg.com)

Version of Vue
3.2.22

Browser
Chrome 96

Can I use vue-debounce with a cdn, like unpkg.com? I have a simple website whose source are static files, and don't even use npm.

it would be great if I could just do something like:

import vueDebounce from 'https://unpkg.com/[email protected]/dist/debounce.min.js';

// or

import vueDebounce from 'https://unpkg.com/[email protected]/src/index.js';

However the former does not work because it is not an ES6 module, and the later fails with a cryptic error:

Uncaught TypeError: debouncedFn is not a function
    at directive.js:84

If this is somehow possible, I'd appreciate a mention in the docs, if not, then this is a feature request :D

When I use debounce directly in the method, I have to add a parenthesis to make it work properly. why?

Version of Vue
Which version of vue are you using?
Vue 2
Browser
What browser are you using?
chrome
Type out the question to the best of your ability!

When I use debounce directly in the method, I have to add a parenthesis to make it work properly.

my method is:

 feedCallback(opts, callback) {            

            debounce(() => {
                this.getUsers();
            }, 400)

  }

the above code does not call the getUsers() method.

But the following code works well with an extra parenthesis at the end of the debounce. Why?

 feedCallback(opts, callback) {       
     
            debounce(() => {
                this.getUsers();
            }, 400)()

  }

Listening for multiple events

Hello, is it possible with this module to listen for multiple events?
For example I want to keep listening to the onkeyup event for most cases, but for our search field it would be good to also trigger on the search event.

The config parameter only seems to allow you to specify one event though. Thoughts?

Support params in function

Will there be support for parameters in the function?

Case:
v-debounce="myFunc('param')"
after mounted component run myFunc three times. If change input function run five times five times etc...

IE11 compatibility

The following line breaks in IE11:

const [amt, t = 'ms'] = String(time).split(/(ms|s)/i)

Seems that this type of array assignment is a bit to much for it. Are you open for updating this to something a bit more old school, or do you know of some method to fix this?

Needs Typescript support

This looks like a very simple and easy to use plugin, but I am using Typescript and getting errors as there is no Types enabled for vue-debounce.

If it will take too long to add could you maybe advise on how to declare a declaration for vue-debounce.

Thanks

Unclear documentation regarding modifiers

Documentation makes it seem like you should be using capitals in your modifiers (such as for fireOnEmpty), but the code actually expects all lower-case (fireonempty). The example given only shows lock which doesn't clarify the situation when all you look at is the documentation.

I think there are three different ways to move forward:

  1. Update the documentation to show that the modifiers should only be lowercase. This would be the least amount of work. (Wouldn't even need a new release, but otherwise would be a patch increment.)

  2. Update the code to accept both lower-case and camelCase modifiers. This would match what the user would expect regarding the documentation as it stands now but also not break current users; however, it would make the codebase more complicated due to having to check against both forms. (Would be a minor version increment.)

  3. Update the code to match the current documentation. This would match what the user would expect regarding the documentation but would break current users; however, the codebase wouldn't increase in complexity. (Would be a major version increment.)

Add CI

I should probably get around to building in some CI tools, just so that the scripts I have can be run as a job with the PRs that have started coming in.

fireOnEmpty triggers double events

When you have fireOnEmpty enabled and you clear out the input, the event fires right away as expected, however I've noticed that it also fires AGAIN after the debounce time.

This is likely due to the debounce time not getting canceled by the fireOnEmpty call.

Probably related to #22 and the issue that was faced here.

How to use with <script setup> syntax?

Version of Vue
3.3.4

If I import custom directive locally to the component, its name under <script setup> syntax should follow specific naming convention:
https://vuejs.org/api/sfc-script-setup.html#using-custom-directives

This is how I'm trying to use it (other part of code omitted for brevity):

 <input name="inputSearch"
                   v-model="inputSearch"
                   v-debounce="test"/>
                   
<script setup lang="ts">
import { vue3Debounce } from 'vue-debounce'

    const vDebounce = {
        debounce: vue3Debounce({ fireOnEmpty: true })
    }; 
    
     const test = async () => {
        console.log(inputSearch.value);
        const searchResult = await searchApi( inputSearch.value);
    };

Nothing happens, just test isn't called on input. No errors. It works if I use traditional export default syntax.

Also, to be honest I would prefer to use debounce as a function in the script part of SFC and keep html standard rather setting custom directives, Maybe there is a such option?

does this fire immediately upon first use?

There's lots of implementations of "debounce" out there - could you clarify if this first the first time immediately, then prevents a second time firing until the debounce has worn off. Or if there's a configuration option for this.

I was hoping to use this to prevent accidental double-clicking of toggleable buttons in a mobile app.

How to pass params?

I tried this

v-debounce:1s='test(form.model.name)'

and I get this error

Uncaught TypeError: i is not a function

Trigger on Vue events

I cannot seem to get the directive to trigger on Vue events.

I have a component which uses the the input event to update the attached v-model. There are several inputs in there (which actually trigger the debounced function), but I also emit them manually: those do not trigger the debounced function.

My simplified component:

<CustomComponent
            v-model="options"
            v-debounce="refreshDefaults" debounce-events="input"/>

I think this might be due to the addEventListener used, as it binds on the HTML element instead of the Vue component. When using @input on the component to trigger the required function without debounce does work.

Make getDirective use more clearer in docs

I have this listed separately from the actual code example, might be a good idea to put the code example where the definition is.

By default getDirective falls back to Vue 2, if you want to use Vue 3 you need to tell that to the function like so: getDirective(3)

The argument structure works like so:
getDirective(version, opts)

Wheres opts is the normal vue-debounce options and version is the version of Vue you want to use.

Maybe I should also re visit this setup in the function, but I fear that would require another major release. More research will go into making this function easier to use.

Denounce on textarea updates.

I wish to use denounce on textarea update event. but seems not working, however it does on enter key which is not the intent.

    Vue.use(vueDebounce)
    // Listening to multiple events
    Vue.use(vueDebounce, {
        listenTo: ['update']
    })

that is my current use.
Is there a way to denounce on textarea changes.
Edit.
Basically what am aiming for is to call a func when user is still typing. The closest example i could think of is WhatsApp that denounce 2hile you still typing, and stop on keys up.

Overwrite fireOnEmpty on a per element basis

Is there an option to set fireOnEmpty for an element which overwrites the default fireOnEmpty?
I have a few inputs where the default fireOnEmpty: true breaks functionality but some others which should fire when they are cleared with a click and only emit input, "".
Something like this would be wonderful:
<b-input v-debounce="onSearch" :v-debounce-fire-on-empty="true" />

Thank you for vue-debounce, it helped a lot already!

Method not firing

<input type="text" v-model="searchQ" v-debounce:400ms="searchQs" debounce-events="keyup" placeholder="Search"/>
Above is my input element, and I have a corresponding method called searchQs.

When typing text in the input I am using keyup event listener, but it seems the function is not being fired?

Any ideas.

Thanks

Failed to resolve directive: debounce #1044

Trying to use this package with [vue-cli-plugin-electron-builder](https://github.com/nklayman/vue-cli-plugin-electron-builder but can't get it to work.

I've installed the vue-debounce package, and added this to background.js:

import Vue from 'vue'
import Vuex from 'vuex'
import vueDebounce from 'vue-debounce'

Vue.use(Vuex, vueDebounce)

I assumed that would work, but I get the following error:

[Vue warn]: Failed to resolve directive: debounce

After a bit of Googling, I see that there is an option to import the module directly into the component, which I have tried:

import { debounce } from 'vue-debounce'

and setting the directive up like this:

export default {
  directives: {
      debounce
  },

which gets rid of the error. But...

My input contains the appropriate syntax: <input v-debounce:300ms="myFunc" /> however "myFunc" is never hit. I just have a simple `console.log("test") in there which never fires...

vue-debounce is not resolved after upgrade to v4.0.1

Describe the bug
I upgrade from vue-debounce to v4.0.0 to v4.0.1 and the following error was raised by typescript compiler:

Could not find a declaration file for module 'vue-debounce'. '/myproject/node_modules/vue-debounce/dist/vue-debounce.min.mjs' implicitly has an 'any' type.
  There are types at '/myproject/node_modules/vue-debounce/types/index.d.ts', but this result could not be resolved when respecting package.json "exports". The 'vue-debounce' library may need to update its package.json or typings.

8 import {debounce} from 'vue-debounce';

It seems that typing file is correct, however it doesn't apply to "vue-debounce.min.mjs".

A possible solution it may be to include "index.d.mts".

Version of Vue
3.4.15

Version of Typescript
Vue-tsc 1.8.27

Version of Vite
4.5.0

Won't work in nuxt 3 build (ok in dev)

Describe the bug

vue-debounce causes a white error screen when visiting my project after doing a Nuxt 3 prod build. It works fine running dev.

Version of Vue

Vue 3

To Reproduce

Install vue-debounce in a nuxt 3 project and add to a component using:

import pkg from 'vue-debounce';

Add as a directive:

export default {
	directives: {
		debounce: vue3Debounce({ lock: true })
	},
}

Then do a prod build and try to visit the running project in the browser.

Expected behavior

Should run in build the same way it runs in dev, but does not.

Desktop (please complete the following information):

Firefox 115.0.3 on MacOS

Additional context

The error message is:

SyntaxError: Named export 'vue3Debounce' not found. The requested module 'vue-debounce' is a CommonJS module, which may not support all module.exports as named exports.

CommonJS modules can always be imported via the default export, for example using:

import pkg from 'vue-debounce';
const { vue3Debounce } = pkg;

But doing it that way doesn't work either.

A couple of things I've read to try to understand what's going on:

https://vitejs.dev/guide/build.html
https://nuxt.com/docs/guide/concepts/esm

Unclear documentation for the use of the debounce function

I have a custom Input component where I needed to add debounce using the function (below code redacted).

My base example looks like this:

<template>
  <div class="my-input">
    <label>My Label</label>
    <div class="my-input__control">
      <input
        @input="triggerOnInputChanged($event.target.value)"
      />      
      <button
        type="submit"
      >
        <span class="btn__icon icon-my-chevron"></span>
      </button>
    </div>
    <span class="text-error"> Some Error</span>
  </div>
</template>

<script>
import { debounce } from 'vue-debounce';

export default {
  name: 'MyInput', 
  props: {
    ...
  },  
  methods: {
    triggerOnInputChanged(value) {
      debounce(() => console.log('triggered change:',value), 300);
    }
  }
};
</script>

Using just debounce as noted in the documentation doesn't seem to trigger the console log.
After having a look at the source code of the directive I noticed that debounce returns the function trigger and a way to cancel it.
Using the following code worked:

<template>
  <div class="my-input">
    <label>My Label</label>
    <div class="my-input__control">
      <input
        @input="triggerOnInputChanged($event.target.value)"
      />      
      <button
        type="submit"
      >
        <span class="btn__icon icon-my-chevron"></span>
      </button>
    </div>
    <span class="text-error"> Some Error</span>
  </div>
</template>

<script>
import { debounce } from 'vue-debounce';

export default {
  name: 'MyInput', 
  props: {
    ...
  },
  data() {
    return {
      debounceFn: undefined
    };
  },  
  methods: {
    triggerOnInputChanged(value) {
      if (this.debounceFn) {
        this.debounceFn.cancel();
      }

      this.debounceFn = debounce(() => this.$emit('on-input-value-changed', value), 300);
      this.debounceFn();
    }
  }
};
</script>

I see that #17 also had some issue using the bare debounce function.

Am I missing something or using the debounce function incorrectly?
Or is the documentation missing a part to make the usage more clearly?

Identify Event Fired

If you have multiple events configured is it possible to tell which event fired the method?

trying to use it on v-select

<v-select
                            name="country"
                            id="address_country"
                            v-model="address.country"
                            label="name"
                            :options="this.countries"
                            v-debounce:1s="getState"
                            @clearable="getState"
                            v-validate="'required'"
                            :class="{ 'is-danger': errors.has('job.country') }"
                    ></v-select>

but on change its not listening to the event

Vue 3 Support Broken

Describe the bug
It's come to my attention that the compatability built into vue-debounce for Vue 3 is not enough. Currently the vnode object works a little bit differently causing the directive to throw an error.

Version of Vue
Which version of vue are you on? 3

To Reproduce
Steps to reproduce the behavior:

  1. setup vue 3 environment
  2. install vue-debounce
  3. plug vue-debounce into vue 3 app instance
  4. boot up app

Expected behavior
Should be able to use the directive as expected

Desktop (please complete the following information):

  • Browser: All Browsers

Additional context
Throws an undefined error on the vnode.data path
Discovered in #71

Debounce delays but doesn't debounce

Version: Vue 3, debounce v3.0.1
Browser: Chrome

I'm attempting to use this package to debounce a method that runs when the @input event of a textarea is fired. Because of my setup, I'm just using debounce directly. I have the debounce module imported, and I wrap the function to debounce inside of a watcher. The result is that when the @input event is fired multiple times in rapid succession, my method call is delayed for the amount of time specified, but then runs for each event that was triggered. I expected it to only run once since the event was fired multiple times within the wait period.

My code is like this:

<Textarea id="content" @input="contentChanged" v-model="form.content" />
import { debounce } from 'vue-debounce';
export default {
    setup (props) {
        const form = useForm({
            content: null
        });
        return form;
    },
    data() {
        changes: 0
    },
    methods: {
          contentChanged(e) {
            this.changes++;
        },
        performAction(val) {
            console.log(val);
        }
    },
    watch: {
        changes: function(val) {
            let newContent = this.form.content;
            debounce(val => {
                this.performAction(val);
            }, 3000)(newContent);
        }
    }
}

When I type the word "test" into the textarea, 3 seconds go by, then the following is printed to the console:
t
te
tes
test

How do I make debounce... debounce? Thanks for the help.

Vue-debounce brakes in IE11

Please, add IE11 support. Once I add vue-debounce to my project I start getting SCRIPT1002: Syntax error that is coming from [email protected] dependency of vue-debounce which is using some syntax that go beyond ES5 IE11 capabilities. I've created a separate issue to reflect the actual cause of the problem here: dhershman1/kyanite#149

vue3Debounce is not a function

Describe the bug
I change to Vue 3 setup on main.js file , and in the console throws me a error that say "vue3Debounce is not a function"

Version of Vue
Vue 3

To Reproduce
I just follow the steps that are in the readme.txt, i didn't do anything else.

Expected behavior
So it works
Desktop (please complete the following information):

  • Chrome
    Additional context
    Before i changed to the Vue 3 setup, i was using the Vue 2 version of vue-debounce in a Vue 3 enviroment, and it works for a long time. But recently a error that says "Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'attrs')" appeared and i decided to move to the Vue 3 version and this error happens. I'm using the last version (4.0.0).

Screenshot from 2022-09-19 16-43-44

v5.0.0 Migration Warning

Hello! I am writing this issue to hopefully warn everyone using this package that I think I'm going to split it up into 2 packages.

I really really really hate the way the code works between Vue 2 and Vue 3, so I think I'm going to dedicate vue-debounce to Vue3, and then I'll make a new package with which name I shall list here at a later date when this project starts.

Thank you for the support and downloading of this silly little tool!

You can now start migrating to the new package here: vue2-debounce

Edit: It's finally here! #85

Doesn't work with SFC syntax

Describe the bug
I'm not sure if this is caused by the SFC syntax, but could very well be.

Version of Vue
3

To Reproduce

  1. Setup the plugin
  2. Create a dummy input element
  3. Set v-debounce with dummy test method
  4. Error pops

Expected behavior
No error

Desktop (please complete the following information):

  • Browser: Chrome

Additional context

vue-debounce.min.js?7965:1 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'attrs')
    at eval (vue-debounce.min.js?7965:1:1)
    at callWithErrorHandling (runtime-core.esm-bundler.js?d2dd:155:1)
    at callWithAsyncErrorHandling (runtime-core.esm-bundler.js?d2dd:164:1)
    at invokeDirectiveHook (runtime-core.esm-bundler.js?d2dd:3744:1)
    at Array.eval (runtime-core.esm-bundler.js?d2dd:4653:1)
    at flushPostFlushCbs (runtime-core.esm-bundler.js?d2dd:356:1)
    at flushJobs (runtime-core.esm-bundler.js?d2dd:401:1)

Using class method breaks inheritance

When using v-debounce="myClass.action"
I get an error that within my class that "this" is undefined.

Here is an example of my class:

class myClass {
	data = {
		name: 'Testing'
	};

	constructor() {
		console.log(this.data);
	}

	public action() {
		console.log(this.data);
	}
}

When the class initializes I get the console log of "{name: Testing}"

But when I Type into my field I get the following response:
Uncaught TypeError: Cannot read property 'data' of undefined

So I am curious if v-debounce is overriding the Class inheritance or something. Or possibly I am not coding this correctly :)

Any help would be appreciated.
Thanks

Should use addEventListener instead of overriding native callback

Overriding the native callbacks can lead to unexpected bugs from client code, especially in a rich ecosystem where we can inspect the listeners.

Don't know the difficulty of appending to $listeners but knowing Vue, it'll probably "just work"

(Additionally, using the native events makes libraries like vue-test-utils, which uses $listeners, not play nicely with vue-debounce)

Does not work with vue router `navigate`

When using router navigate, I get error from router

vue-router.esm.js?8c4f:1244 Uncaught TypeError: Cannot read properties of undefined (reading 'metaKey')

Version of Vue
"vue": "^2.6.10"
"vue-router": "^3.5.2"

To Reproduce

<router-link v-slot="{navigate}" custom :to="{ name: 'Page' }">
    <div v-debounce:200="navigate" debounce-events="click"> Button </div>
</router-link>

:debounce-events="['blur']" not overriding

Vue 2.6
Chrome (latest version)

The :debounce-events doesn't seem to override on Vuetify components. Vuetify is a custom component and the docs seem to say the vue-debounce works with custom components.

Here is a codesandbox showing the issue:
https://codesandbox.io/s/vue-debounce-with-vuetify-blur-issue-7bp8lh?file=/src/App.vue:307-334

You'll see that if you update the input by typing some text, the debounced function still fires after 1s even though the :debounce-events is set to "blur", not "input". From the documentation, the debounce-events should override any other event types, correct?

Debounce deep watch handler

Seems not working inside deep watch handler func:

import { debounce } from 'vue-debounce';

...
watch: {
  someData: {
    handler() {
      debounce(() => {
        this.updateProfile();
      }, 1300);
    },
    deep: true,
  },
},

Set default timeout other than 300ms?

Hello. Thanks for this great module! Is it possible to implement setting of custom default timeout during install of this plugin (Vue.use(...)) ? Thanks

fireOnEmpty interrupting curried functions

Seems like having fireOnEmpty enabled causes some interruption issues with curry based functions that are holding a param.

also likely this is related to #22 and possibly #23

Not sure what might be causing this to fire as soon as focus is put on the input. Will need to research it more.

Add debounce delay parameter for custom debounces

Thanks for creating this lib, i was going to make one myself if i couldn't find one and this is perfect!

In my specific situation though, the user has the ability to configure the debounce delay for each field itself ... would be good to have a prop that we could pass to define the debounce delay (somehow). I know it's possible to define it at a global level with a dynamic value, but what about on a per input basis?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.