Vue3 Forms

In this section, we introduce the application of Vue forms.

We can use the v-model directive on form<input>、<textarea>and<select>elements to create two-way data binding.

v-model automatically selects the correct method to update elements based on the control type.

v-model ignores the initial values of the value, checked, and selected attributes of all form elements, and instead uses the initial values declared in the data option.

Internally, v-model uses different properties and emits different events for different input elements:

  • text and textarea elements usevalueproperty andinputevent;
  • checkbox and radio usecheckedproperty andchangeevent;
  • select fields willvalueuse as a property andchangeas an event.

Input

The example demonstrates using v-model to implement two-way data binding on input and textarea elements:

<div id="app"> <p>input element:</p> <input v-model="message" placeholder="Edit me..."> <p>The input form message is: {{ message }}</p> <p>textarea element:</p> <textarea v-model="message2" placeholder="Multi-line text input..."></textarea> <p>The textarea form message is:</p> <p style="white-space: pre">{{ message2 }}</p> </div> <script>const app = { data() { return { message: '', message2: 'Example\r\nhttps://www.example.com' } } } Vue.createApp(app).mount('#app')</script>

Try it Yourself »
Interpolation does not work in the textarea element; you need to use v-model instead:
<!-- 错误 -->
<textarea>{{ text }}</textarea>

<!-- 正确 -->
<textarea v-model="text"></textarea>

Checkbox

If a checkbox is single, it is a boolean value; if multiple, they bind to the same array:

Checkbox

The following example demonstrates two-way data binding of 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="example" value="Example" v-model="checkedNames"> <label for="example">Example</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>The selected value is: {{ checkedNames }}</span> </div> <script> const app = { data() { return { checked : false, checkedNames: [] } } } Vue.createApp(app).mount('#app') </script>

Try it Yourself »

The effect of checking the checkboxes in the example is shown below:

Radio buttons

The following example demonstrates two-way data binding of radio buttons:

Radio buttons

<div id="app"> <input type="radio" id="example" value="Example" v-model="picked"> <label for="example">Example</label> <br> <input type="radio" id="google" value="Google" v-model="picked"> <label for="google">Google</label> <br> <span>The selected value is: {{ picked }}</span> </div> <script> const app = { data() { return { picked : 'Example' } } } Vue.createApp(app).mount('#app') </script>

Try it Yourself »

After selection, the effect is shown below:

Select list

The following example demonstrates two-way data binding of a dropdown list:

select

<div id="app"> <select v-model="selected" name="site"> <option value="">Select a website</option> <option value="www.example.com">Example</option> <option value="www.google.com">Google</option> </select> <div id="output">The selected website is: {{selected}}</div> </div> <script> const app = { data() { return { selected: '' } } } Vue.createApp(app).mount('#app') </script>

Try it Yourself »

Select Example, the output effect is shown below:

When multiple selection is enabled, it binds to an array:

select

<div id="app"> <select v-model="selected" name="fruit" multiple> <option value="www.example.com">Example</option> <option value="www.google.com">Google</option> <option value="www.taobao.com">Taobao</option> </select> <div id="output">The selected websites are: {{selected}}</div> </div> <script> const app = { data() { return { selected: '' } } } Vue.createApp(app).mount('#app') </script>

Try it Yourself »

Select Example and Google:

Usev-forloop to output 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.example.com', options: [ { text: 'Example', value: 'www.example.com' }, { text: 'Google', value: 'www.google.com' }, { text: 'Taobao', value: 'www.taobao.com' } ] } } } Vue.createApp(app).mount('#app') </script>

Try it Yourself »

Select Example:

Value binding

For radio buttons, checkboxes, and select options, the v-model bound value is usually a static string (for checkboxes, it can also be a boolean):

<!-- 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>

But sometimes we may want to bind the value to a dynamic property of the current active instance. In this case, v-bind can be used. In addition, v-bind can bind input values to non-string values.

Checkbox:

<input type="checkbox" v-model="toggle" true-value="yes" false-value="no" />
...
// 选中时
vm.toggle === 'yes'
// 取消选中 
vm.toggle === 'no'

Radio:

<input type="radio" v-model="pick" v-bind:value="a" />
// 当选中时
vm.pick === vm.a

Select option:

<select v-model="selected">
  <!-- 内联对象字面量 -->
  <option :value="{ number: 123 }">123</option>
</select>
// 当被选中时
typeof vm.selected // => 'object'
vm.selected.number // => 123

Modifiers

.lazy

By default, v-model synchronizes the input value with the data on the input event, but you can add a lazy modifier to instead synchronize on the change event:

<!-- 在 "change" 而不是 "input" 事件中更新 -->
<input v-model.lazy="msg" >

.number

If you want to automatically convert the user's input value to Number type (if the conversion result of the original value is NaN, the original value is returned), you can add a number modifier to v-model to process the input value:

<input v-model.number="age" type="number">

This is often useful because when type="number", the value entered in HTML is always returned as a string type.

.trim

If you want to automatically filter leading and trailing spaces from user input, you can add a trim modifier to v-model to filter the input:

<input v-model.trim="msg">
Other extensions