The following code has not been checked, but I wanted to explain more about debounce and how "v-on" or "@" events in Vue work.
On your <input>
tag you can use <input @input="fetchData" v-model="name">
as @dziraf explained, and do a bunch of extra work for the extra variable. OR ...
TO SEND ARGUMENTS, you simply have to explicitly include the "EVENT" variable first (in Vue.js events it's name is $event), then any you choose to add:
<input
@input="fetchData($event, 'Custom Values', customVariables)"
v-model="name"
>
Now you have access to all variables sent to "your function" or the "debounced function" (which is simply a wrapped version of any function you send it):
methods: {
fetchData:
_.debounce(
(e, customVariable1=undefined, customVariable2=undefined) => {
console.log('Input argument is: ' + e.target.value);
}, 500),
...
HINT: The "=undefined" in the 2 customVariables is used to make them optional.
WARNING: Be CAREFUL if you will implement multiple instances of this component on a single page, then using your debounce function in methods:
is NOT recommended due to some encapsulation issues during some initial Vue Lifecycle hooks. Also I believe you cannot call the .cancel()
method if needed when you some other user interaction and stop the function before the delay is over.
It's recommended to save the function to a variable in the created()
lifecycle rather than a method:
:
created() {
this.fetchData = _.debounce(
(e, customVariable1=undefined, customVariable2=undefined) => {
console.log('Input argument is: ' + e.target.value);
}, 500);
}
Now, you can call the .cancel()
method to properly garbage collect:
beforeDestroy() {
this.fetchData.cancel();
}
Or, have a "Cancel" button or call from another UI element:
<button @click="fetchData.cancel();">Cancel the Request</button>
You can try this code to see the minor differences in the encapsulation:
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>
<div id="app">
<div>Using debounce as a data() variable declared in created():</div>
<create-change ref="counter1"></create-change>
<create-change ref="counter2"></create-change>
<create-change ref="counter3"></create-change>
<create-change ref="counter4"></create-change>
<br />
<br />
<div>Using debounce as a Method:</div>
<method-change ref="counter5"></method-change>
<method-change ref="counter6"></method-change>
<method-change ref="counter7"></method-change>
<method-change ref="counter8"></method-change>
</div>
JS
Vue.component('create-change', {
template:
`
<button @click="changeContent($event,'any custom value')">
Click to change my value: {{ i }}
</button>
`,
data: function(){
return { i: 0 };
},
created() {
this.changeContent = _.debounce(function(e, val=0){
if (val) { this.i = val } // or reference a method here
}, 1000)
},
});
Vue.component('method-change', {
template:
`
<button @click="changeContent($event,'any custom value')">
Click to change my value: {{ i }}
</button>
`,
data: function(){
return { i: 0 };
},
methods: {
// WARNING: Can have encapsulation issues
changeContent: _.debounce(function(e, val=0){
if (val) { this.i = val }
}, 1000),
},
});
new Vue({
el: '#app',
mounted () {
this.$refs.counter1.changeContent(null,1);
this.$refs.counter2.changeContent(null,2);
this.$refs.counter3.changeContent(null,3);
this.$refs.counter4.changeContent(null,4);
this.$refs.counter5.changeContent(null,5);
this.$refs.counter6.changeContent(null,6);
this.$refs.counter7.changeContent(null,7);
this.$refs.counter8.changeContent(null,8);
}
});
CSS
#app {
margin: 20px;
font-size: 20px;
font-family: Arial, sans-serif;
}