A while back, in 2019, I wrote an article demonstrating how to create a custom Vue component, and handle the v-model
capabilities:
https://dev.to/valentinprgnd/wrap-a-text-field-in-a-component-with-vue-js-gak
I recently discovered an alternative way to do it, which does not require a watcher, thus making the code much faster and less resource heavy.
The original post suggested this method:
<template>
<div class="custom-input">
<input v-model="localValue" placeholder="Enter your name">
</div>
</template>
<script>
export default {
name: "TextField",
props: {
value: String // 1. Receives the value as a prop
},
data() {
return {
localValue: ""
};
},
created() {
this.localValue = this.value; // 2. Copy the value in a local value variable
// Set a watcher to emit the changes to the parent component
this.$watch("localValue", value => {
this.$emit("input", value);
});
}
};
</script>
While functional, the use of a watcher here can be really resource heavy (particularly if you create a lot of such components).
A better approach would be to use a computed property, like so:
<template>
<div class="custom-input">
<input v-model="localValue" placeholder="Enter your name">
</div>
</template>
<script>
export default {
name: "TextField",
props: {
value: String // 1. Receives the value as a prop
},
computed: {
localValue: {
get() {
return this.value;
},
set(value) {
this.$emit('input', value);
}
}
};
</script>
Not only it reduces the boilerplate code, but it also avoids the use of a watcher, making your component faster and less resource heavy 🎉
Top comments (0)