Form Inputs Sync to Refs Automatically
v-model — Two-Way Binding
v-model is shorthand for :value plus @input. It works on inputs, selects, checkboxes, textareas, and custom components.
What you'll learn
- Bind a text input with v-model
- Bind a checkbox / select
- Use v-model on a custom component
v-model wires a form input directly to a ref. It saves you from writing a value bind and an event listener for every field.
Text Inputs
<script setup lang="ts">
import { ref } from 'vue'
const name = ref('')
</script>
<template>
<input v-model="name" placeholder="Your name" />
<p>Hello {{ name }}</p>
</template> That is exactly equivalent to writing it the long way:
<input
:value="name"
@input="name = ($event.target as HTMLInputElement).value"
/> Checkboxes, Selects, Radios
v-model adapts to the input type. A single checkbox is a boolean; multiple checkboxes share an array.
<script setup lang="ts">
import { ref } from 'vue'
const agree = ref(false)
const toppings = ref<string[]>([])
const color = ref('red')
</script>
<template>
<input type="checkbox" v-model="agree" />
<input type="checkbox" value="cheese" v-model="toppings" />
<input type="checkbox" value="olives" v-model="toppings" />
<select v-model="color">
<option>red</option>
<option>blue</option>
</select>
</template> Custom Components
To make your own component v-model-able, call defineModel inside <script setup>:
<script setup lang="ts">
const model = defineModel<string>()
</script>
<template>
<input :value="model" @input="model = ($event.target as HTMLInputElement).value" />
</template> Then a parent uses it like any input: <MyInput v-model="name" />.