Vuejs 2: debounce not working on a watch option Vuejs 2: debounce not working on a watch option vue.js vue.js

Vuejs 2: debounce not working on a watch option


Another variation to @Bert's answer is to build the watcher's function in created(),

// SO: Vuejs 2: debounce not working on a watch optionconsole.clear()Vue.component("debounce",{  props : {    debounce : {      type : Number,      default : 500    }  },  template:`    <div>      <input type="text" v-model="term">    </div>  `,  data(){    return {      term: "",      debounceFn: null    }  },  created() {    this.debounceFn = _.debounce( () => {      console.log('Debounced term: ' + this.term);    }, this.debounce)  },  watch : {    term : function () {      this.debounceFn();    }  },})new Vue({  el: "#app"})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script><div id="app">  <debounce :debounce="2000"></debounce></div>

Example on CodePen


The primary issue here is using this.debounce as the interval when defining your debounced function. At the time _.debounce(...) is run (when the component is being compiled) the function is not yet attached to the Vue, so this is not the Vue and this.debounce will be undefined. That being the case, you will need to define the watch after the component instance has been created. Vue gives you the ability to do that using $watch.

I would recommend you add it in the created lifecycle handler.

created(){  this.unwatch = this.$watch('term', _.debounce((newVal) => {     console.log('Debounced term: ' + this.term);  }, this.debounce))},beforeDestroy(){  this.unwatch()}

Note above that the code also calls unwatch which before the component is destroyed. This is typically handled for you by Vue, but because the code is adding the watch manually, the code also needs to manage removing the watch. Of course, you will need to add unwatch as a data property.

Here is a working example.

console.clear()Vue.component("debounce",{  props : {    debounce : {      type : Number,      default : 500    }  },  template:`    <input type="text" v-model="term">  `,  data(){    return {      unwatch: null,      term: ""    }  },  created(){    this.unwatch = this.$watch('term', _.debounce((newVal) => {      console.log('Debounced term: ' + this.term);    }, this.debounce))  },  beforeDestroy(){    this.unwatch()  }})new Vue({  el: "#app"})
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script><script src="https://unpkg.com/vue@2.4.2"></script><div id="app">  <debounce :debounce="250"></debounce></div>


new Vue({  el: '#term',  data: function() {    return {      term: 'Term',      debounce: 1000    }  },  watch: {    term : _.debounce(function () {        console.log('Debounced term: ' + this.term);    }, this.debounce)  }})
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.js"></script><div id="term">  <input v-model="term"></div>