Vue v-model
Two-way data binding in Vue
🔄 What is v-model?
v-model creates two-way data binding on form inputs. When the input changes, the data updates automatically, and when data changes, the input updates too.
<div id="app">
<input v-model="message" placeholder="Type here">
<p>You typed: {{ message }}</p>
</div>
<script src="https://unpkg.com/vue@3"></script>
<script>
Vue.createApp({
data() {
return { message: '' }
}
}).mount('#app')
</script>
v-model Features
Text Input
Bind text and textarea elements
<input v-model="text">
Checkboxes
Bind boolean or array values
<input type="checkbox" v-model="checked">
Radio Buttons
Select one option from many
<input type="radio" v-model="picked">
Select Dropdown
Choose from dropdown options
<select v-model="selected">
🔹 Text Input Binding
The most common use of v-model is with text inputs. It automatically syncs the input value with your data property.
<div id="app">
<label>Enter your name:</label>
<input v-model="name" type="text" placeholder="Your name">
<p>Hello, {{ name || 'Guest' }}!</p>
<label>Message:</label>
<textarea v-model="message" rows="3"></textarea>
<p>{{ message }}</p>
</div>
<script src="https://unpkg.com/vue@3"></script>
<script>
Vue.createApp({
data() {
return {
name: '',
message: ''
}
}
}).mount('#app')
</script>
Output:
Hello, Guest!
🔹 Checkbox Binding
Use v-model with checkboxes for boolean values or arrays. Single checkbox binds to boolean, multiple checkboxes bind to an array.
🔸 Single Checkbox
<div id="app">
<input type="checkbox" id="agree" v-model="agreed">
<label for="agree">I agree to terms</label>
<p>Agreed: {{ agreed }}</p>
</div>
<script src="https://unpkg.com/vue@3"></script>
<script>
Vue.createApp({
data() {
return {
agreed: false
}
}
}).mount('#app')
</script>
🔸 Multiple Checkboxes
<div id="app">
<input type="checkbox" id="html" value="HTML" v-model="skills">
<label for="html">HTML</label>
<input type="checkbox" id="css" value="CSS" v-model="skills">
<label for="css">CSS</label>
<input type="checkbox" id="js" value="JavaScript" v-model="skills">
<label for="js">JavaScript</label>
<p>Selected: {{ skills }}</p>
</div>
<script src="https://unpkg.com/vue@3"></script>
<script>
Vue.createApp({
data() {
return {
skills: []
}
}
}).mount('#app')
</script>
Output:
Selected: []
🔹 Radio Button Binding
Radio buttons with v-model allow selecting one option from multiple choices. The selected value is stored in the data property.
<div id="app">
<h3>Choose your favorite color:</h3>
<input type="radio" id="red" value="Red" v-model="color">
<label for="red">Red</label>
<input type="radio" id="blue" value="Blue" v-model="color">
<label for="blue">Blue</label>
<input type="radio" id="green" value="Green" v-model="color">
<label for="green">Green</label>
<p>Selected color: {{ color }}</p>
</div>
<script src="https://unpkg.com/vue@3"></script>
<script>
Vue.createApp({
data() {
return {
color: 'Red'
}
}
}).mount('#app')
</script>
Output:
Choose your favorite color:
Selected color: Red
🔹 Select Dropdown Binding
Use v-model with select elements to bind dropdown selections. Supports single and multiple selections.
🔸 Single Select
<div id="app">
<select v-model="country">
<option disabled value="">Choose a country</option>
<option>USA</option>
<option>Canada</option>
<option>UK</option>
<option>Australia</option>
</select>
<p>Selected: {{ country }}</p>
</div>
<script src="https://unpkg.com/vue@3"></script>
<script>
Vue.createApp({
data() {
return {
country: ''
}
}
}).mount('#app')
</script>
🔸 Multiple Select
<div id="app">
<select v-model="languages" multiple>
<option>JavaScript</option>
<option>Python</option>
<option>Java</option>
<option>C++</option>
</select>
<p>Selected: {{ languages }}</p>
</div>
<script src="https://unpkg.com/vue@3"></script>
<script>
Vue.createApp({
data() {
return {
languages: []
}
}
}).mount('#app')
</script>
Output:
Selected:
🔹 v-model Modifiers
Vue provides modifiers to change v-model behavior. These modifiers make common tasks easier without extra code.
Common Modifiers:
- .lazy - Sync after "change" event instead of "input"
- .number - Automatically convert input to number
- .trim - Automatically trim whitespace
<div id="app">
<!-- Lazy update -->
<input v-model.lazy="lazyMsg" placeholder="Lazy update">
<p>{{ lazyMsg }}</p>
<!-- Number conversion -->
<input v-model.number="age" type="number">
<p>Age: {{ age }} (type: {{ typeof age }}))</p>
<!-- Trim whitespace -->
<input v-model.trim="username" placeholder="Username">
<p>'{{ username }}'</p>
</div>
<script src="https://unpkg.com/vue@3"></script>
<script>
Vue.createApp({
data() {
return {
lazyMsg: '',
age: 0,
username: ''
}
}
}).mount('#app')
</script>