0Pricing
Vue Academy · Lesson

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

  1. v-model: Two-Way Binding Internals
  2. v-on Event Modifiers
  3. v-bind Dynamic and Multiple Bindings
  4. Writing Custom Directives
← Back to Vue Academy