Suggest an editImprove this articleRefine the answer for “How does two-way binding (v-model) work?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)`v-model` is a **directive** that binds a component variable's value to a form element (input, textarea, select, etc.) **in both directions**: when the data changes, the UI updates, and when the user types into the form, the variable updates. **Key point:** Vue creates this two-way synchronization without you having to write handlers by hand.Shown above the full answer for quick recall.Answer (EN)Image## 1. What is `v-model` `v-model` is a **directive** that binds a component variable's value to a form element (**input, textarea, select, etc.**) **in both directions**: - when the data changes → the UI updates - when the user types into the form → the variable updates In other words, `v-model` = **"data ↔ UI"**. --- ## 2. Basic usage example ```javascript <template> <input v-model="message" placeholder="Enter text" /> <p>You entered: {{ message }}</p> </template> <script setup> import { ref } from 'vue' const message = ref('') </script> ``` ### What happens: - When the user types text → `message.value` updates. - When `message.value` changes → the `input` automatically shows the new value. Vue creates **two-way synchronization** without you having to write handlers by hand. --- ## 3. How `v-model` works "under the hood" Take this code: ```javascript <input v-model="message" /> ``` Vue **translates** it into plain attributes and events: ```javascript <input :value="message" @input="message = $event.target.value" /> ``` In other words: - `:value` - **one-way data binding** (from the component → to the DOM); - `@input` - **feedback** (from the DOM → to the component). That is how you get **two-way data binding**. --- ## 4. Working with different element types | Element | What it binds | Example | |---|---|---| | `<input type="text">` | `value` ↔ text | `<input v-model="text" />` | | `<input type="checkbox">` | `checked` ↔ boolean | `<input type="checkbox" v-model="isChecked" />` | | `<input type="radio">` | `checked` ↔ value | `<input type="radio" value="A" v-model="choice" />` | | `<select>` | `value` ↔ selected value | `<select v-model="option">` | | `<textarea>` | `value` ↔ text | `<textarea v-model="comment"></textarea>` | --- ## 5. Two-way binding between **components** `v-model` can be used not only with form elements, but also **to link a parent and a child component**. ### Parent: ```javascript <UserInput v-model="username" /> ``` ### Child component: ```javascript <template> <input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" /> </template> <script setup> defineProps(['modelValue']) defineEmits(['update:modelValue']) </script> ``` The parent passes a value through `v-model` → the `modelValue` prop The child reports changes through the `update:modelValue` event > This is the standard `v-model` contract in Vue 3: > **prop:** `modelValue` → **emit:** `update:modelValue` --- ## 6. Several `v-model`s on one component Vue 3 lets you use **several independent v-models** with names: ```javascript <MyInput v-model:title="pageTitle" v-model:content="pageText" /> ``` Child component: ```javascript <script setup> defineProps(['title', 'content']) defineEmits(['update:title', 'update:content']) </script> ``` --- ## 7. `v-model` modifiers Vue offers convenient **modifiers** that transform the data on input: | Modifier | Description | Example | |---|---|---| | `.lazy` | Updates the value only after `change`, not `input` | `<input v-model.lazy="text" />` | | `.trim` | Automatically trims whitespace from the start and end | `<input v-model.trim="name" />` | | `.number` | Converts the value to a number | `<input v-model.number="age" />` | --- ## 8. Under the hood of reactivity When you write `v-model="x"`: 1. Vue tracks that the DOM element **depends on** `x`; 2. when `x` changes, the `value` attribute updates; 3. on an `input`/`change` event, Vue triggers a **reverse update** → `x = $event.target.value`. These two directions form a **reactive loop**, keeping the UI and the state instantly in sync. --- ## Summary > `v-model` is the mechanism for two-way data binding in Vue.js. > > It automatically synchronizes the component's state and the UI: > > - **from code → to the DOM** (`:value="..."`) > - **from the DOM → to code** (`@input="..."`) > > It works both with form elements and with components, > and supports **modifiers** and **multiple models**.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.