Understanding v-model in custom components

As you know, v-model is shorthand for v-on:input and v-bind:value="value" on a given element. It allows us to two-way bind a particular element's value, and the events that it emits to one of our internal state properties.

When talking about component composition, however, we need to take extra things into consideration.

In order for a custom component to be able to implement the v-model contract, we have to make sure that two things happen. That's right! We need to ensure that the component has a value property and that it $emits an input event.

There is a way to change this default behavior by using the model property, but it is out of the scope of this book. If you want to tell your component to use a different property, or a different event for v-model, take a look at https://vuejs.org/v2/api/#model.

Let's put this theory into practice. We're going to modify our BaseInput component, in order to be able to use a v-model binding. First, let's add a value property, and hook it to <input>:

props: {
label: {
type: String,
required: true
},
type: {
type: String,
default: 'text',
validator(value) {
return ['text', 'email', 'password'].includes(value);
}
},


// Add this new prop
value: {
type: String,
required: true
}
}

Now that we have our new value prop, we need to bind it to the value of <input>. Be sure to remove the old v-model from it, though! Have a look at the following example:

<input :value="value" type="text" class="form-control">

Almost there; now we need to make sure that <input> dispatches input events whenever it updates. So, we need to add an event handler that $emits this information.

Important! Before we continue, let me tell you about a very common gotcha when working with v-model and forms. Not all inputs are created equally! The <input> text elements (text, email, and password) and <textarea> are easy. They fire input events that we can listen to for our v-model binding. But, what about select, checkboxes, and radio?

The Vue documentation makes it super clear, so I'm going to quote it:

"v-model internally uses different properties and emits different events for different input elements:

  • text and textarea elements use value property and input event;
  • checkboxes and radiobuttons use checked property and change event;
  • select fields use value as a prop and change as an event."

Now that we have got that theory out of the way, let's actually listen to our event:

<input 
:value="value"
:type="type"
class="form-control"
@input="$emit('input', $event.target.value)"
>

Congratulations! Our BaseInput component is ready to be used.

Now that we have a clear understanding of v-model and custom components, we're going to get to use our component inside our form. It will make it far more readable, dynamic, and easy to maintain.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.143.181