How to Handle Form Input in Vue with v-model
Capture what a user types in three steps: hold the value in a ref, bind the input with v-model, and read it back — with a live demo that echoes the typed text.
Overview
Handling text input in Vue comes down to connecting a form field to a piece of reactive state so the two always agree. You store the value in a ref, bind the field to it with v-model, and from then on the ref holds whatever the user typed — ready to read, validate, or send. This is the standard, recommended approach and it takes only a few lines.
Steps
1. Hold the value in a ref
Start with the state. Create a ref to hold the field's value, initialised to an empty string for a text input. This ref is the single source of truth for what is in the field — everything else in these steps just keeps it and the input synchronised.
<script setup>
import { ref } from 'vue';
const text = ref('');
</script>
2. Bind the input with v-model
Add v-model="text" to the input element. This sets up a two-way binding: the field displays the ref's current value, and every keystroke writes the new value straight back into the ref. There is no event handler to wire up by hand — v-model does both directions for you.
<template>
<input v-model="text" />
</template>
3. Read the value
The ref now holds the live value, so you can use it anywhere. In the template read it by bare name — {{ text }} — and it updates as the user types; in script read text.value to validate it or send it to an API. Because it is reactive, anything derived from it stays in sync automatically.
<template>
<input v-model="text" />
<p>You typed: {{ text }}</p>
</template>
4. Understand what v-model expands to
It helps to know that v-model is not magic — on a text input it is shorthand for binding :value and listening to @input. Writing the two out by hand produces exactly the same result, which is worth seeing once so the binding never feels opaque.
<!-- these two inputs behave identically -->
<input v-model="text" />
<input :value="text" @input="text = $event.target.value" />
Runnable example
The complete, running version — type in the field and the text echoes below it live, straight from the ref:
Common pitfalls
If you need to transform input as it is typed — force uppercase, strip spaces — reach for the expanded :value + @input form from step 4, or add a v-model modifier such as .trim. That gives you a hook to adjust the value on its way into the ref, which the plain binding does not expose.
Frequently asked questions
How do I get the value of an input in Vue?
ref, bind the input with v-model="yourRef", and the ref holds whatever the user types. Read it by bare name in the template or through .value in script.What is v-model shorthand for on a text input?
v-model="text" is shorthand for :value="text" combined with @input="text = $event.target.value". It binds the value one way and updates the ref on input the other way.Do I use .value with v-model?
v-model="text" — because the template auto-unwraps the ref. Writing v-model="text.value" breaks the binding. You only use .value when reading the ref in script.