表单输入绑定 | Form Input Bindings
When dealing with forms on the frontend, we often need to sync the state of form input elements with corresponding state in JavaScript. It can be cumbersome to manually wire up value bindings and change event listeners:
在前端处理表单时,我们常常需要将表单输入框的内容同步给 JavaScript 中相应的变量。手动连接值绑定和更改事件监听器可能会很麻烦:
template
<input
:value="text"
@input="event => text = event.target.value">
The v-model
directive helps us simplify the above to:
v-model
指令帮我们简化了这一步骤:
template
<input v-model="text">
In addition, v-model
can be used on inputs of different types, <textarea>
, and <select>
elements. It automatically expands to different DOM property and event pairs based on the element it is used on:
另外,v-model
还可以用于各种不同类型的输入,<textarea>
、<select>
元素。它会根据所使用的元素自动使用对应的 DOM 属性和事件组合:
<input>
with text types and<textarea>
elements usevalue
property andinput
event;- 文本类型的
<input>
和<textarea>
元素会绑定value
property 并侦听input
事件; <input type="checkbox">
and<input type="radio">
usechecked
property andchange
event;<input type="checkbox">
和<input type="radio">
会绑定checked
property 并侦听change
事件;<select>
usesvalue
as a prop andchange
as an event.<select>
会绑定value
property 并侦听change
事件。
| 注意
v-model
will ignore the initial value
, checked
or selected
attributes found on any form elements. It will always treat the current bound JavaScript state as the source of truth. You should declare the initial value on the JavaScript side, using reactivity APIs.
v-model
会忽略任何表单元素上初始的 value
、checked
或 selected
attribute。它将始终将当前绑定的 JavaScript 状态视为数据的正确来源。你应该在 JavaScript 中使用响应式系统的 API来声明该初始值。
基本用法 | Basic Usage
文本 | Text
template
<p>Message is: {{ message }}</p>
<input v-model="message" placeholder="edit me" />
Message is:
Note | 注意
对于需要使用 IME 的语言 (中文,日文和韩文等),你会发现 v-model
不会在 IME 输入还在拼字阶段时触发更新。如果你的确想在拼字阶段也触发更新,请直接使用自己的 input
事件监听器和 value
绑定而不要使用 v-model
。
多行文本 | Multiline text
template
<span>Multiline message is:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<textarea v-model="message" placeholder="add multiple lines"></textarea>
Multiline message is:
Note that interpolation inside <textarea>
won't work. Use v-model
instead.
注意在 <textarea>
中是不支持插值表达式的。请使用 v-model
来替代:
template
<!-- bad -->
<!-- 错误 -->
<textarea>{{ text }}</textarea>
<!-- good -->
<!-- 正确 -->
<textarea v-model="text"></textarea>
复选框 | Checkbox
Single checkbox, boolean value:
单一的复选框,绑定布尔类型值:
template
<input type="checkbox" id="checkbox" v-model="checked" />
<label for="checkbox">{{ checked }}</label>
We can also bind multiple checkboxes to the same array or Set value:
我们也可以将多个复选框绑定到同一个数组或集合的值:
js
const checkedNames = ref([])
template
<div>Checked names: {{ checkedNames }}</div>
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames" />
<label for="jack">Jack</label>
<input type="checkbox" id="john" value="John" v-model="checkedNames" />
<label for="john">John</label>
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames" />
<label for="mike">Mike</label>
Checked names: []
In this case, the checkedNames
array will always contain the values from the currently checked boxes.
在这个例子中,checkedNames
数组将始终包含所有当前被选中的框的值。
单选按钮 | Radio
template
<div>Picked: {{ picked }}</div>
<input type="radio" id="one" value="One" v-model="picked" />
<label for="one">One</label>
<input type="radio" id="two" value="Two" v-model="picked" />
<label for="two">Two</label>
Picked:
选择器 | Select
Single select:
单个选择器的示例如下:
template
<div>Selected: {{ selected }}</div>
<select v-model="selected">
<option disabled value="">Please select one</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
Selected:
Note | 注意
If the initial value of your v-model
expression does not match any of the options, the <select>
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.
如果 v-model
表达式的初始值不匹配任何一个选择项,<select>
元素会渲染成一个“未选择”的状态。在 iOS 上,这将导致用户无法选择第一项,因为 iOS 在这种情况下不会触发一个 change 事件。因此,我们建议提供一个空值的禁用选项,如上面的例子所示。
Multiple select (bound to array):
多选 (值绑定到一个数组):
template
<div>Selected: {{ selected }}</div>
<select v-model="selected" multiple>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
Selected: []
Select options can be dynamically rendered with v-for
:
选择器的选项可以使用 v-for
动态渲染:
js
const selected = ref('A')
const options = ref([
{ text: 'One', value: 'A' },
{ text: 'Two', value: 'B' },
{ text: 'Three', value: 'C' }
])
template
<select v-model="selected">
<option v-for="option in options" :value="option.value">
{{ option.text }}
</option>
</select>
<div>Selected: {{ selected }}</div>
值绑定 | Value Bindings
For radio, checkbox and select options, the v-model
binding values are usually static strings (or booleans for checkbox):
对于单选按钮,复选框和选择器选项,v-model
绑定的值通常是静态的字符串 (或者对复选框是布尔值):
template
<!-- `picked` is a string "a" when checked -->
<!-- `picked` 在被选择时是字符串 "a" -->
<input type="radio" v-model="picked" value="a" />
<!-- `toggle` is either true or false -->
<!-- `toggle` 只会为 true 或 false -->
<input type="checkbox" v-model="toggle" />
<!-- `selected` is a string "abc" when the first option is selected -->
<!-- `selected` 在第一项被选中时为字符串 "abc" -->
<select v-model="selected">
<option value="abc">ABC</option>
</select>
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.
但有时我们可能希望将该值绑定到当前组件实例上的动态数据。这可以通过使用 v-bind
来实现。此外,使用 v-bind
还使我们可以将选项值绑定为非字符串的数据类型。
复选框 | Checkbox
template
<input
type="checkbox"
v-model="toggle"
true-value="yes"
false-value="no" />
true-value
and false-value
are Vue-specific attributes that only work with v-model
. Here the toggle
property's value will be set to 'yes'
when the box is checked, and set to 'no'
when unchecked. You can also bind them to dynamic values using v-bind
:
true-value
和 false-value
是 Vue 特有的 attributes,仅支持和 v-model
配套使用。这里 toggle
属性的值会在选中时被设为 'yes'
,取消选择时设为 'no'
。你同样可以通过 v-bind
将其绑定为其他动态值:
template
<input
type="checkbox"
v-model="toggle"
:true-value="dynamicTrueValue"
:false-value="dynamicFalseValue" />
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.
true-value
和 false-value
attributes 不会影响 value
attribute,因为浏览器在表单提交时,并不会包含未选择的复选框。为了保证这两个值 (例如:“yes”和“no”) 的其中之一被表单提交,请使用单选按钮作为替代。
单选按钮 | Radio
template
<input type="radio" v-model="pick" :value="first" />
<input type="radio" v-model="pick" :value="second" />
pick
会在第一个按钮选中时被设为 first
,在第二个按钮选中时被设为 second
。
选择器选项 | Select Options
template
<select v-model="selected">
<!-- inline object literal -->
<!-- 内联对象字面量 -->
<option :value="{ number: 123 }">123</option>
</select>
v-model
supports value bindings of non-string values as well! In the above example, when the option is selected, selected
will be set to the object literal value of { number: 123 }
.
v-model
同样也支持非字符串类型的值绑定!在上面这个例子中,当某个选项被选中,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). You can add the lazy
modifier to instead sync after change
events:
默认情况下,v-model
会在每次 input
事件后更新数据 (IME 拼字阶段的状态例外)。你可以添加 lazy
修饰符来改为在每次 change
事件后更新数据:
template
<!-- synced after "change" instead of "input" -->
<!-- 在 "change" 事件后同步更新而不是 "input" -->
<input v-model.lazy="msg" />
.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:
如果你想让用户输入自动转换为数字,你可以在 v-model
后添加 .number
修饰符来管理输入:
template
<input v-model.number="age" />
If the value cannot be parsed with parseFloat()
, then the original (string) value is used instead. In particular, if the input is empty (for instance after the user clearing the input field), an empty string is returned. This behavior differs from the DOM property valueAsNumber
.
如果该值无法被 parseFloat()
处理,那么将返回原始值。
The number
modifier is applied automatically if the input has type="number"
.
number
修饰符会在输入框有 type="number"
时自动启用。
.trim
If you want whitespace from user input to be trimmed automatically, you can add the trim
modifier to your v-model
-managed inputs:
如果你想要默认自动去除用户输入内容中两端的空格,你可以在 v-model
后添加 .trim
修饰符:
template
<input v-model.trim="msg" />
组件上的 v-model
| v-model
with Components
If you're not yet familiar with Vue's components, you can skip this for now.
如果你还不熟悉 Vue 的组件,那么现在可以跳过这个部分。
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 Usage with v-model
in the Components guide.
HTML 的内置表单输入类型并不总能满足所有需求。幸运的是,我们可以使用 Vue 构建具有自定义行为的可复用输入组件,并且这些输入组件也支持 v-model
!要了解更多关于此的内容,请在组件指引中阅读配合 v-model
使用。