Vue3 Forms
In this section, we will introduce the application of forms in Vue.
We can use the v-model
directive to create two-way data bindings on form <input>
, <textarea>
, and <select>
elements.
v-model
automatically selects the correct method to update the element based on the control type.
v-model
ignores the initial values of the value
, checked
, and selected
attributes of all form elements and uses the initial values declared in the data
option.
text
andtextarea
elements use thevalue
attribute andinput
event;checkbox
andradio
use thechecked
attribute andchange
event;select
fields use thevalue
attribute andchange
event.
Input Fields
The following example demonstrates two-way data binding using v-model
on input
and textarea
elements:
<div id="app">
<p>input element:</p>
<input v-model="message" placeholder="Edit me...">
<p>input form message is: {{ message }}</p>
<p>textarea element:</p>
<textarea v-model="message2" placeholder="Multi-line text input..."></textarea>
<p>textarea form message is:</p>
<p style="white-space: pre">{{ message2 }}</p>
</div>
<script>
const app = {
data() {
return {
message: '',
message2: 'tutorialpro.org\r\nhttps://www.tutorialpro.org'
}
}
}
Vue.createApp(app).mount('#app')
</script>
<!-- Incorrect -->
<textarea>{{ text }}</textarea>
<!-- Correct -->
<textarea v-model="text"></textarea>
Checkboxes
A single checkbox binds to a boolean value, while multiple checkboxes bind to the same array:
Checkboxes
The following example demonstrates two-way data binding for checkboxes:
<div id="app">
<p>Single checkbox:</p>
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>
<p>Multiple checkboxes:</p>
<input type="checkbox" id="tutorialpro" value="tutorialpro" v-model="checkedNames">
<label for="tutorialpro">tutorialpro</label>
<input type="checkbox" id="google" value="Google" v-model="checkedNames">
<label for="google">Google</label>
<input type="checkbox" id="taobao" value="Taobao" v-model="checkedNames">
<label for="taobao">taobao</label>
<br>
<span>Selected values: {{ checkedNames }}</span>
</div>
<script>
const app = {
data() {
return {
checked : false,
checkedNames: []
}
}
}
Vue.createApp(app).mount('#app')
</script>
Radio Buttons
The following example demonstrates two-way data binding for radio buttons:
Radio Buttons
<div id="app">
<input type="radio" id="tutorialpro" value="tutorialpro" v-model="picked">
<label for="tutorialpro">tutorialpro</label>
<br>
<input type="radio" id="google" value="Google" v-model="picked">
<label for="google">Google</label>
<br>
<span>Selected value: {{ picked }}</span>
</div>
<script>
const app = {
data() {
return {
picked : 'tutorialpro'
}
}
}
Vue.createApp(app).mount('#app')
</script>
Select List
The following example demonstrates two-way data binding for a dropdown list:
Select
<div id="app">
<select v-model="selected" name="site">
<option value="">Choose a website</option>
<option value="www.tutorialpro.org">tutorialpro</option>
<option value="www.google.com">Google</option>
</select>
<div id="output">
Selected website: {{selected}}
</div>
</div>
<script>
const app = {
data() {
return {
selected: ''
}
}
}
Vue.createApp(app).mount('#app')
</script>
For multiple selections, it binds to an array:
Select
<div id="app">
<select v-model="selected" name="fruit" multiple>
<option value="www.tutorialpro.org">tutorialpro</option>
<option value="www.google.com">Google</option>
<option value="www.taobao.com">Taobao</option>
</select>
<div id="output">
Selected websites: {{selected}}
</div>
</div>
<script>
const app = {
data() {
return {
selected: ''
}
}
}
Vue.createApp(app).mount('#app')
</script>
Using v-for
to loop through options:
Select
<div id="app" class="demo">
<select v-model="selected">
<option v-for="option in options" :value="option.value">
{{ option.text }}
</option>
</select>
<span>Selected: {{ selected }}</span>
</div>
<script>
const app = {
data() {
return {
selected: 'www.tutorialpro.org',
options: [
{ text: 'tutorialpro', value: 'www.tutorialpro.org' },
{ text: 'Google', value: 'www.google.com' },
{ text: 'Taobao', value: 'www.taobao.com' }
]
}
}
}
Vue.createApp(app).mount('#app')
</script>
Value Binding
For radio buttons, checkboxes, and select options, v-model
binding values are usually static strings (or booleans for checkboxes):
<!-- When selected, `picked` is the string "a" -->
<input type="radio" v-model="picked" value="a" />
<!-- `toggle` is true or false -->
<input type="checkbox" v-model="toggle" />
<!-- When the first option is selected, `selected` is the string "abc" -->
<select v-model="selected">
<option value="abc">ABC</option>
</select>
However, you might want to bind the value to a dynamic property on the current active instance. This can be done with v-bind
. Additionally, using v-bind
allows binding input values to non-string values.
Checkbox:
<input type="checkbox" v-model="toggle" true-value="yes" false-value="no" />
...
// When checked
vm.toggle === 'yes'
// When unchecked
vm.toggle === 'no'
Radio:
<input type="radio" v-model="pick" v-bind:value="a" />
// When selected
vm.pick === vm.a
Select Option:
<select v-model="selected">
<!-- Inline object literal -->
<option :value="{ number: 123 }">123</option>
</select>
// When selected
typeof vm.selected // => 'object'
vm.selected.number // => 123
Modifiers
.lazy
By default, v-model
syncs the input with the data on the input
event. You can add a lazy
modifier to change this to the change
event:
<!-- Sync on "change" instead of "input" -->
<input v-model.lazy="msg" >
.number
To automatically convert user input to a Number type, you can add a number
modifier to v-model
:
<input v-model.number="age" type="number">
This is often useful because even with type="number"
, the value from HTML inputs is always a string.
.trim
To automatically trim user input, you can add a trim
modifier to v-model
:
<input v-model.trim="msg">