Frontend DevelopmentVueJs Tutorials

Vue 3 Manipulating v-model With The defineModel macro

Vue 3 Manipulating v-model With The defineModel macro

Two-way data binding is key to creating dynamic apps. Vue.js makes it easy to handle two-way model binding using the v-model directive. In Vue 3.4 the defineModel macro takes this further. It gives you more type safety and cleans up your code. 

 

 

v-model provides two-way data binding. What does that mean? Changes in the UI update the data, and changes in the data update the UI. v-model is actually shorthand. It combines passing a prop and emitting an event. This helps keep your components in sync.

Before defineModel, v-model used props and $emit. This involved more code. You had to define a prop and emit an update event. This approach worked, but was a bit clunky. It had issues, like more code and potential type errors.

 

Basic usage:

MyForm.vue

<script setup>
  const nameModel = defineModel();
</script>

<template>
  <p>
    <label>Name</label>
    <input type="text" v-model="nameModel" />
  </p>
</template>

Declaring a model simply by calling the defineModel() macro, and then passing it to the v-model directive. Now in parent component you can use v-model as well with the child component:

App.vue

<script setup>
  ...
  const data = ref('');
</script>

<template>
  <MyForm v-model="data" />
</template>

Now the data is synced in parent and child component. As we know previously to implement this without defineModel() we have to pass a prop and emit an event like so:

MyForm.vue

<script setup>
  const props = defineProps(['modelValue']);
  const emit = defineEmits(['update:modelValue']);
</script>

<template>
  <input
    type="text"
    :value="props.modelValue"
    @input="emit('update:modelValue', ($event.target as HTMLInputElement).value)"
  />
</template>

This approach is working, however you have to write more code and makes the code base more complicated especially if you want to handle multiple v-model in the same component. 

defineModel automatically creates the prop and event for v-model. No more manual work! It reduces the amount of code needed. The syntax is straightforward. 

 

Multiple v-model On The Same Component

With defineModel() macro we can handle multiple v-model on the same child component by specifying an argument to v-model i.e “v-model:argument“:

App.vue

<script setup>
  ...
  const name = ref('');
  const email = ref('');
</script>
<template>
  <MyForm v-model="name" v-model:email="email" />
</template>

In the child component specify the argument name to defineModel() as the first parameter:

MyForm.vue

<script setup>
  const nameModel = defineModel();
  const emailModel = defineModel('email');    // defineModel with argument
</script>
<template>
  <p>
    <label>Name</label>
    <input type="text" v-model="nameModel" />
  </p>

  <p>
    <label>Email</label>
    <input type="email" v-model="emailModel" />
  </p>
</template>

Each property passed with v-model to the child component is synced with the parent as usual. This way we can create complex forms with little code.

 

0 0 votes
Article Rating

What's your reaction?

Excited
0
Happy
0
Not Sure
0
Confused
0

You may also like

Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments