Vue Directives: v-model
The v-model directive is a powerful tool in Vue.js for creating two-way data bindings. It simplifies handling form input and keeping your data synchronized with the user interface.
What does v-model do?
Essentially, v-model is syntactic sugar for a combination of:
:valueattribute binding (one-way data binding from the component's data to the input)@inputevent listener (listening for user input changes and updating the component's data)
Basic Usage
The most common use case is with <input> elements:
<template>
<div>
<input type="text" v-model="message">
<p>Message: {{ message }}</p>
</div>
</template>
<script>
export default {
data() {
return {
message: ''
}
}
}
</script>
In this example, any changes made in the input field will automatically update the message data property, and vice-versa. The paragraph will dynamically display the current value of message.
v-model with Different Input Types
v-model behaves slightly differently depending on the input type:
Text & Textarea: Two-way binding to the
valueproperty.<input type="text" v-model="name"> <textarea v-model="description"></textarea>Checkbox: Two-way binding to the
checkedproperty. The value bound tov-modelwill be a boolean (trueif checked,falseif not).<input type="checkbox" id="agree" v-model="agreed"> <label for="agree">I agree</label>Radio: Two-way binding to the
valueproperty. Multiple radio buttons with the samev-modelwill share the same bound value. The selected radio button's value will be assigned to thev-modelvariable.<input type="radio" id="one" value="one" v-model="picked"> <label for="one">One</label> <input type="radio" id="two" value="two" v-model="picked"> <label for="two">Two</label>Select: Two-way binding to the
valueproperty.Single Select: The
valuebound tov-modelwill be the selected option's value.<select v-model="selected"> <option value="a">A</option> <option value="b">B</option> </select>Multiple Select: The
valuebound tov-modelwill be an array of the selected option values.<select v-model="selectedOptions" multiple> <option value="a">A</option> <option value="b">B</option> <option value="c">C</option> </select>
Modifiers
v-model supports modifiers to customize its behavior:
.lazy: Updates the data only after the input loses focus (onblurevent instead ofinput). Useful for performance optimization when dealing with expensive operations.<input type="text" v-model.lazy="message">.number: Automatically converts the input value to a number. Useful for numeric inputs.<input type="number" v-model.number="age">.trim: Automatically trims whitespace from the input value.<input type="text" v-model.trim="username">
Custom Input Components
v-model can also be used with custom components. The component needs to:
- Accept a
valueprop. - Emit an
inputevent when the value changes.
// CustomInput.vue
<template>
<input :value="value" @input="$emit('input', $event.target.value)">
</template>
<script>
export default {
props: {
value: String
}
}
</script>
// Parent Component
<template>
<div>
<CustomInput v-model="myValue" />
<p>Value: {{ myValue }}</p>
</div>
</template>
<script>
import CustomInput from './CustomInput.vue';
export default {
components: {
CustomInput
},
data() {
return {
myValue: ''
}
}
}
</script>
Important Considerations
v-modelonly works with form elements and custom components that follow the specified prop/event convention.- Be mindful of data types when using
.number. If the input is not a valid number, it will be converted toNaN. - For complex form validation, consider using a dedicated form validation library.