In the past, setting up two-way data binding between components was a somewhat manual process, compounded by the immutability of props. This meant that extra caution was needed when dealing with props drilling, as inadvertent modifications by child components could lead to loss of reactivity. You had to define properties and events, ensuring to emit them or reactivity is lost. Discover how Vue 3.4's new defineModel
compiler macro simplifies this process and allows props mutations.
Example: Prior to defineModel() compiler macro was introduced in Vue 3.4
<!-- MyComponent.vue --> <script setup> const props = defineProps(['modelValue']) const emit = defineEmits(['update:modelValue']) </script> <template> <input :value="props.modelValue" @input="emit('update:modelValue', $event.target.value)" /> <!-- pass the prop --> <MyComponent v-model="count" />
Example: implement the same MyComponent.vue shown above in Vue 3.4
With Vue 3.4, the introduction of the defineModel
compiler macro significantly streamlines this process. For example, we can achieve the same outcome as the above example using defineModel exclusively.
<!-- MyComponent.vue --> <script setup> const model = defineModel() </script> <template> <input v-model="model" /> </template> <!-- pass the prop --> <MyComponent v-model="count" />
The value from defineModel() is a ref object, similar to any other ref object created using ref() method, but with a unique feature: it facilitates a two-way binding between parent and child component.
- Its .value is synchronized with the parent's v-model-bound value.
- If altered by the child, it automatically updates the parent-bound value. Say goodbye to the hassle of using
emit('update:modelValue', $event.target.value)
This also allows child component to pass props data to other components (Props drilling) without worrying about underlying mutation.
What is difference?
defineModel
simplifies the process of creating two-way binding between parent and child components by automatically generating the necessary props and events. Instead of manually defining the modelValue
prop and emitting the update:modelValue
event, you can use defineModel
to handle these tasks for you. This reduces the amount of boilerplate code you need to write and makes your components cleaner and more concise.
How to use custom prop name with defineModel() ?
To use a custom prop name or multiple v-models, you'll need to specify an identifier as an argument, such as v-model:title
previously. The same customization can be achieved with defineModel.
Example:
<!-- MyComponent.vue --> <script setup> const firstName = defineModel('firstName') const lastName = defineModel('lastName') </script> <template> <input type="text" v-model="firstName" /> <input type="text" v-model="lastName" /> </template> <!-- pass the prop --> const first = ref('Akram'); const last = ref('Wahid'); <MyComponent v-model:first-name="first" v-model:last-name="last" />
In conclusion,
While the defineModel macro may appear simple, those familiar with managing multiple component bindings understand the tediousness of manual upkeep. Vue once again streamlines our workflow, easing the burden of component synchronization.
If you have any other questions, experience or insights on "How to use Vue 3.4 defineModel() compiler macro" please feel free to leave your thoughts in the comments bellow, Don't forget to share the posts.
Be the first one to write a response :(
{{ reply.member.name }} - {{ reply.created_at_human_readable }}