可以用 v-model 指令在表单 <input>、<textarea> 及 <select> 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但 v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。
v-model 会忽略所有表单元素的 value、checked、selected 特性的初始值而总是将 Vue 实例的数据作为数据来源。你应该通过 JavaScript 在组件的 data 选项中声明初始值。
<template>
<div>
<input type="text" value="init value">
<input type="checkbox" id="checkbox" checked="checked">
<select>
<option value="">请选择</option>
<option selected>A</option>
<option>B</option>
<option>C</option>
</select>
</div>
</template>
页面显示如下:
使用v-model之后
<template>
<div>
<input type="text" value="init value" v-model="inputValue">
<input type="checkbox" id="checkbox" v-model="isChecked">
<select v-model="selectValue">
<option>请选择</option>
<option value='A' selected>A</option>
<option value='B'>B</option>
<option value='C'>C</option>
</select>
</div>
</template>
data () {
return {
inputValue: '',
isChecked: false,
selectValue: 'B'
}
}
此时页面显示如下:
表单元素
输入框
<input v-model="message" placeholder="edit me">
多行文本
<textarea v-model="message" placeholder="add multiple lines"></textarea>
复选框
<input type="checkbox" id="checkbox" v-model="checked">
多个复选框,绑定到同一个数组:
<div id='example-3'>
<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>
<br>
<span>Checked names: {{ checkedNames }}</span>
</div>
new Vue({
el: '#example-3',
data: {
checkedNames: []
}
})
单选按钮
<input type="radio" id="one" value="One" v-model="picked">
<input type="radio" id="two" value="Two" v-model="picked">
v-model绑定同一个data属性上可以将单选按钮成组。
选择框
单选
<select v-model="selectValue">
<option disabled value="">请选择</option>
<option value='A' selected>A</option>
<option value='B'>B</option>
<option value='C'>C</option>
</select>
多选:添加multiple
<select multiple v-model="selectValue">
<option disabled value="">请选择</option>
<option value='A' selected>A</option>
<option value='B'>B</option>
<option value='C'>C</option>
</select>
selectValue为数组
修饰符
先看一下input的input & change事件
<template>
<div>
<input type="text" value="init value" @input="input" @change="changeInput" v-model="inputValue">
<br>
<span>input输入框的值:{{inputValue}}</span>
</div>
</template>
methods: {
input () {
console.log('调用input事件')
},
changeInput () {
console.log('调用change事件')
}
}
说一下看到的情况:每一次的输入都会触发input事件,并且双向数据绑定的值会更新。当输入完内容鼠标不聚焦与input框才会触发change事件。
.lazy
在默认情况下,v-model 在每次 input 事件触发后将输入框的值与数据进行同步 (除了上述输入法组合文字时)。你可以添加 lazy 修饰符,从而转变为使用 change 事件进行同步:
<input type="text" value="init value" @input="input" @change="changeInput" v-model.lazy="inputValue">
.number
如果想自动将用户的输入值转为数值类型,可以给 v-model 添加number修饰符。
官方还有一句话:
这通常很有用,因为即使在 type="number" 时,HTML 输入元素的值也总会返回字符串。如果这个值无法被 parseFloat() 解析,则会返回原始的值。
这句话我的测试发现其中是有一些问题的。
<template>
<div>
<input type="text" value="init value" @input="input" @change="changeInput()" v-model.number="inputValue">
<br>
<span>input输入框的值:{{inputValue}}</span>
</div>
</template>
methods: {
input () {
console.log('input事件输入值类型:' + typeof this.inputValue)
},
changeInput () {
console.log('change事件输入值类型:' + typeof this.inputValue)
}
}
请看下面的图示:
我看到的结果是:
- 当我先输入的是字符串,当前属性的类型为string,并且一直是string。这也是当前官方里说的结果。
- 当我先输入的是数字,当前属性的类型为number,并且后面我在输入string,model不会更新,并且当change触发之后,输入框的内容退回到只有数字的情况。
.trim
如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符
<input type="text" value="init value" @input="input" @change="changeInput()" v-model.trim="inputValue">
表单现有的库
正常的开发估计还是会使用现有的库。
** 由于浏览器都有默认的校验行为,一般会使用 novalidate="true"禁用浏览器的默认行为。
至于库的学习需要等到根据项目的选择再决定。