v-model: Two-Way Binding Internals
v-model compiles to :modelValue + @update:modelValue, custom v-model names, v-model on components.
v-model: Two-Way Binding Internals is a free Vue Academy lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Vue Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
What v-model Really Is
v-model looks like magic two-way binding, but it is just shorthand for a value binding plus an event listener. Understanding what it expands to lets you use it on inputs and custom components alike.
v-model on a Text Input
On a native input, v-model binds the value and listens for input events. These two lines are equivalent.
<!-- shorthand -->
<input v-model="text" />
<!-- expanded -->
<input :value="text" @input="text = $event.target.value" />Two Pieces: Bind and Listen
The :value pushes state into the element; the @input pushes user changes back into state. Together they create the two-way effect.
v-model on Components Differs
On a custom component, v-model uses a different prop and event: modelValue and update:modelValue. Native value/input are only for native elements.
<!-- on a component -->
<MyInput v-model="text" />
<!-- expands to -->
<MyInput :model-value="text" @update:model-value="text = $event" />Implementing v-model in a Child
To support v-model, a child declares a modelValue prop and emits update:modelValue when the value should change.
<script setup>
defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
function onInput(e) { emit('update:modelValue', e.target.value) }
</script>The Child Template
The child binds the incoming prop to the input and emits on change. The parent never knows the internal details.
<template>
<input :value="modelValue" @input="onInput" />
</template>Named v-model Arguments
You can target a specific prop by naming the model: v-model:title uses the prop title and event update:title.
<!-- parent -->
<MyDialog v-model:title="pageTitle" />
<!-- expands to -->
<MyDialog :title="pageTitle" @update:title="pageTitle = $event" />Declaring a Named Model in the Child
The child simply declares a prop and matching event with that name.
<script setup>
defineProps(['title'])
const emit = defineEmits(['update:title'])
</script>Multiple v-model on One Component
Because each model has its own name, you can bind several at once. A user form component might expose v-model:first and v-model:last simultaneously.
<UserName
v-model:first="firstName"
v-model:last="lastName"
/>Why This Design Is Powerful
Since v-model is just props plus events, custom components feel exactly like native inputs to their consumers. Multiple named models let one component manage several two-way bindings cleanly.
Common Pitfall
Do not mutate the modelValue prop directly inside the child — that breaks one-way prop flow. Always emit the update event and let the parent own the state.
Quick Check
Test your v-model internals knowledge.
Recap
You uncovered how v-model works:
- On inputs it expands to
:value+@input. - On components it uses
modelValue+update:modelValue. - Named models (
v-model:title) target specific props/events. - You can use multiple v-models on one component.
Frequently asked questions
Is the “v-model: Two-Way Binding Internals” lesson free?
Yes — the full text of “v-model: Two-Way Binding Internals” is free to read here on the web, and the Vue Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Vue Academy course, upgrade to CoddyKit PRO.
What will I learn in “v-model: Two-Way Binding Internals”?
v-model compiles to :modelValue + @update:modelValue, custom v-model names, v-model on components. You practise Vue Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Vue Academy?
No prior experience is required. Vue Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “v-model: Two-Way Binding Internals” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Vue Academy lesson?
Yes. Every Vue Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- v-model: Two-Way Binding Internals
- v-on Event Modifiers
- v-bind Dynamic and Multiple Bindings
- Writing Custom Directives