# Form Input Bindings
## Basic Usage
You can use the `v-model` directive to create two-way data bindings on form input, textarea, and select elements. It automatically picks the correct way to update the element based on the input type. Although a bit magical, `v-model` is essentially syntax sugar for updating data on user input events, plus special care for some edge cases.
::: tip Note
`v-model` will ignore the initial `value`, `checked` or `selected` attributes found on any form elements. It will always treat the current active instance data as the source of truth. You should declare the initial value on the JavaScript side, inside the `data` option of your component.
:::
`v-model` internally uses different properties and emits different events for different input elements:
- text and textarea elements use `value` property and `input` event;
- checkboxes and radiobuttons use `checked` property and `change` event;
- select fields use `value` as a prop and `change` as an event.
::: tip Note
For languages that require an [IME](https://en.wikipedia.org/wiki/Input_method) (Chinese, Japanese, Korean etc.), you'll notice that `v-model` doesn't get updated during IME composition. If you want to cater for these updates as well, use `input` event instead.
:::
### Text
```html
Message is: {{ message }}
```
See the Pen
Handling forms: basic v-model by Vue (@Vue )
on CodePen .
### Multiline text
```html
Multiline message is:
{{ message }}
```
See the Pen
Handling forms: textarea by Vue (@Vue )
on CodePen .
Interpolation on textareas won't work. Use `v-model` instead.
```html
```
### Checkbox
Single checkbox, boolean value:
```html
{{ checked }}
```
See the Pen
Handling forms: checkbox by Vue (@Vue )
on CodePen .
Multiple checkboxes, bound to the same Array:
```html
Jack
John
Mike
Checked names: {{ checkedNames }}
```
```js
Vue.createApp({
data() {
return {
checkedNames: []
}
}
}).mount('#v-model-multiple-checkboxes')
```
See the Pen
Handling forms: multiple checkboxes by Vue (@Vue )
on CodePen .
### Radio
```html
One
Two
Picked: {{ picked }}
```
```js
Vue.createApp({
data() {
return {
picked: ''
}
}
}).mount('#v-model-radiobutton')
```
See the Pen
Handling forms: radiobutton by Vue (@Vue )
on CodePen .
### Select
Single select:
```html
Please select one
A
B
C
Selected: {{ selected }}
```
```js
Vue.createApp({
data() {
return {
selected: ''
}
}
}).mount('#v-model-select')
```
See the Pen
Handling forms: select by Vue (@Vue )
on CodePen .
:::tip Note
If the initial value of your `v-model` expression does not match any of the options, the `` element will render in an "unselected" state. On iOS this will cause the user not being able to select the first item because iOS does not fire a change event in this case. It is therefore recommended to provide a disabled option with an empty value, as demonstrated in the example above.
:::
Multiple select (bound to Array):
```html
A
B
C
Selected: {{ selected }}
```
See the Pen
Handling forms: select bound to array by Vue (@Vue )
on CodePen .
Dynamic options rendered with `v-for`:
```html
{{ option.text }}
Selected: {{ selected }}
```
```js
Vue.createApp({
data() {
return {
selected: 'A',
options: [
{ text: 'One', value: 'A' },
{ text: 'Two', value: 'B' },
{ text: 'Three', value: 'C' }
]
}
}
}).mount('#v-model-select-dynamic')
```
See the Pen
Handling forms: select with dynamic options by Vue (@Vue )
on CodePen .
## Value Bindings
For radio, checkbox and select options, the `v-model` binding values are usually static strings (or booleans for checkbox):
```html
ABC
```
But sometimes we may want to bind the value to a dynamic property on the current active instance. We can use `v-bind` to achieve that. In addition, using `v-bind` allows us to bind the input value to non-string values.
### Checkbox
```html
```
```js
// when checked:
vm.toggle === 'yes'
// when unchecked:
vm.toggle === 'no'
```
:::tip Tip
The `true-value` and `false-value` attributes don't affect the input's `value` attribute, because browsers don't include unchecked boxes in form submissions. To guarantee that one of two values is submitted in a form (e.g. "yes" or "no"), use radio inputs instead.
:::
### Radio
```html
```
```js
// when checked:
vm.pick === vm.a
```
### Select Options
```html
123
```
```js
// when selected:
typeof vm.selected // => 'object'
vm.selected.number // => 123
```
## Modifiers
### `.lazy`
By default, `v-model` syncs the input with the data after each `input` event (with the exception of IME composition as [stated above](#vmodel-ime-tip)). You can add the `lazy` modifier to instead sync after `change` events:
```html
```
### `.number`
If you want user input to be automatically typecast as a number, you can add the `number` modifier to your `v-model` managed inputs:
```html
```
This is often useful, because even with `type="number"`, the value of HTML input elements always returns a string. If the value cannot be parsed with `parseFloat()`, then the original value is returned.
### `.trim`
If you want whitespace from user input to be trimmed automatically, you can add the `trim` modifier to your `v-model`-managed inputs:
```html
```
## `v-model` with Components
> If you're not yet familiar with Vue's components, you can skip this for now.
HTML's built-in input types won't always meet your needs. Fortunately, Vue components allow you to build reusable inputs with completely customized behavior. These inputs even work with `v-model`! To learn more, read about [custom inputs](./component-basics.html#using-v-model-on-components) in the Components guide.