DEVELOPER GUIDEUsing Lodash/Underscore in Vue 3
Hey millionaires,
I have been working on Vue JS for a while and recently encountered a problem while trying to use Lodash in Vue Components.
The issue I faced was
this is undefined
I tried for like 2 hours but can't figure out what was going on until I found a solution and the reason of the problem.
This is due to scope of function and keywords.
following example explains the scope working differently between two function types.
// This variable is in the window's scope
window.value = 'Bound to the window';
const object = {
// This variable is in the object's scope
value: 'Bound to the object',
arrowFunction: () => {
// The arrow function uses the window's scope for `this`
console.log(this.value); // 'Bound to the window'
},
regularFunction() {
// The regular function uses the object's scope for `this`
console.log(this.value); // 'Bound to the object'
}
};
This is what my vue component looked like
<template>
<div>
<button @click="GeneratePreview">Generate</button>
</div>
</template>
<script>
// LODASH
import { debounce } from "lodash";
export default {
name: "Code Editor",
data() {
return
};
},
mounted() {
this.createHTMLEditor(this.$refs.htmlEditor, "htmlmixed");
this.createCSSEditor(this.$refs.cssEditor, "css");
this.createJavascriptEditor(this.$refs.jsEditor, "javascript");
this.HTMLEditor.on("change", () => {
if (this.autoRun) {
debounce(this.generatePreview, 250)
}
});
this.CSSEditor.on("change", () => {
if (this.autoRun) {
debounce(this.generatePreview, 250)
}
});
this.JavascriptEditor.on("change", () => {
if (this.autoRun) {
debounce(this.generatePreview, 250)
}
});
},
methods: {
generatePreview() {
this.html = this.HTMLEditor.getValue();
this.css = this.CSSEditor.getValue();
this.javascript = this.JavascriptEditor.getValue();
},
},
};
</script>
Here's the fix and proper way to use Lodash inside vue component.
created() {
this.debouncedMethod = debounce(this.debouncedMethod, 250);
},
methods: {
methodToDebounce() {
// Do some things here
}
}
so component looks like this after fixing.
<template>
<div>
<button @click="GeneratePreview">Generate</button>
// other bunch of code
</div>
</template>
<script>
// LODASH
import { debounce } from "lodash";
export default {
name: "Code Editor",
data() {
return
};
},
created() {
this.debouncedPreview = debounce(this.debouncedPreview, 250);
},
mounted() {
this.createHTMLEditor(this.$refs.htmlEditor, "htmlmixed");
this.createCSSEditor(this.$refs.cssEditor, "css");
this.createJavascriptEditor(this.$refs.jsEditor, "javascript");
this.HTMLEditor.on("change", () => {
if (this.autoRun) {
this.debouncedPreview();
}
});
this.CSSEditor.on("change", () => {
if (this.autoRun) {
this.debouncedPreview();
}
});
this.JavascriptEditor.on("change", () => {
if (this.autoRun) {
this.debouncedPreview();
}
});
},
methods: {
generatePreview() {
this.html = this.HTMLEditor.getValue();
this.css = this.CSSEditor.getValue();
this.javascript = this.JavascriptEditor.getValue();
},
},
};
</script>
That's all and that simple. All I did was wrapping our function in debounce function and returned a new one that already has debouncing built in. and now calling this.debouncedMethod()
will call the debounced version.
Hope it will help you guys.
The solution is referenced from this article.