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)