第6章 表单与v-model
6.1 基本用法
Vue.js提供了v-model指令,用于表单上的数据双向绑定,例如在输入框使用时,输入的内容会实时绑定到数据。该指令用于实现单选、多选、下拉选择、输入框等,用于完成数据的录入、验证等。
<div id="app">
<input type="text" v-model="message" placeholder="输入...">
<p>输入的内容为:{{message}}</p>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
message:""
}
})
</script>
注意:使用v-model后,表单控件显示值只依赖绑定的数据,与初始化value属性值无关。使用v-model时,如果用中文输入法输入中文,一般在没有选定词组前,也就是拼音阶段Vue是不会更新数据的,只在当敲下汉字时才会更新。如果希望是实时更新的,可使用@input来代替v-model。事实上,v-model是一个特殊的语法糖,只不过它能够在不同的表单上智能处理。
<div id="app">
<input type="text" @input="handleInput" placeholder="输入...">
<p>输入的内容为:{{message}}</p>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
message:''
},
methods:{
handleInput:function(e){
this.message = e.target.value;
}
}
})
</script>
单选按钮:
单选按钮在单独使用时,不需要v-model,直接使用v-bind绑定布尔值即可。例如:
<div id="app">
<input type="radio" :checked="picked">
<label>单选按钮</label>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
picked:true
},
})
</script>
如果组合使用实现互斥选择需要用v-model配合value使用:
<div id="app">
<input type="radio" v-model="picked" value="html" id="html">
<label for="html">HTML</label>
<br>
<input type="radio" v-model="picked" value="js" id="js">
<label for="js">JavaScript</label>
<br>
<input type="radio" v-model="picked" value="css" id="css">
<label for="css">CSS</label>
<br>
<p>选择的项是:{{picked}}</p>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
picked:'js'
},
})
</script>
复选按钮:
复选框分为单独使用和组合使用,复选框单独使用时,也是用v-model来绑定一个布尔值。组合使用时需要v-model和value一起使用,多个数值绑定到同一种类型的数组数据中,value值在数组中,选择过程是双向的,选中时,数值也会push到数组中。
<div id="app">
<input type="checkbox" v-model="checked" value="html" id="html">
<label for="html">HTML</label>
<br>
<input type="checkbox" v-model="checked" value="js" id="js">
<label for="js">JavaScript</label>
<br>
<input type="checkbox" v-model="checked" value="css" id="css">
<label for="css">CSS</label>
<br>
<p>选择的项是:{{checked}}</p>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
checked:{'html','css'}
},
})
</script>
选择列表:
选择列表就是下拉选择器,分为单选和多选两种方式。
<div id="app">
<select v-model="selected">
<option>html</option>
<option value='js'>JavaScript</option>
<option>css</option>
</select>
<p>选择的项是:{{selected}}</p>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
selected:'html'
},
})
</script>
<option>是备选项,如果含有value属性,v-model会优先匹配value的值;如果没有,就会直接匹配<option>的text,比如选中第二项是,selected的值是js,而不是JavaScript。
给<selected>添加属性multiple就可以多选,这种v-mode绑定的是一个数组。
在业务中,<option>经常用v-for动态输出,value和text也是用v-bind来动态输出的。
<div id="app">
<select v-model="selected">
<option v-for="option in options"
:value="option.value">{{option.text}}</option>
</select>
<p>选择的项是:{{selected}}</p>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
selected:'html',
options:[
{
text:'HTML',
value:'html',
},
{
text:'JavaScript',
value:'js',
},
{
text:'CSS',
value:'css',
}
]
},
})
</script>
6.2 绑定值
在实际业务中绑定值需要动态数值,这时可以用v-bind来实现。
单选按钮:
<div id="app">
<input type="radio" v-model="picked" :value="value">
<label>单选按钮</label>
<p>{{picked}}</p>
<p>{{value}}</p>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
picked:false,
value:123
},
})
</script>
在选中时,app.picked===app.value,值都是123
复选框:
<div id="app">
<input type="checkbox" v-model="toggle" :true-value:"value1"
:false-value:"value2">
<label>复选框</label>
<p>{{toggle}}</p>
<p>{{value1}}</p>
<p>{{value2}}</p>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
toggle:false,
value1:'a',
value2:'b',
},
})
</script>
勾选时,app.toggle===app.value1;未勾选时,app.toggle===app.value2
选择列表:
<div id="app">
<select v-model="selected">
<option :value="{number:123}">123</option>
</select>
{{selected.number}}
</div>
<script>
var app = new Vue({
el:'#app',
data:{
selected:''
},
})
</script>
6.3 修饰符
v-model也有修饰符,用于控制数据同步的时机。
.lazy:
在输入框中,v-model默认是在input事件中同步输入框的数据(除中文外),使用.lazy修饰符会在change事件中同步。
<div id="app">
<input type="text" v-model.lazy="message">
<p>输入的内容为:{{message}}</p>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
message:''
}
})
</script>
这时,message不是实时改变的,只在失去焦点或者回车才更新。
.number
使用.number可以将输入转换为Number类型,否则虽然你输入的是数字,但它的类型依然是String。
.trim:
修饰符.trim可以自动过滤首尾空格。
<div id="app">
<input type="text" v-model.trim="message">
<p>{{message}}</p>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
message:''
}
})
</script>