开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第12天,点击查看活动详情
前面我们介绍过,v-model指令主要用于表单元素。今天我们就来介绍一下不同类型表单元素(原生表单元素)是如何使用v-model进行绑定的。
表单元素收集
下面我们以一个例子为例,先写一个form表单。代码如下:
<template>
<div class="hello">
<form>
<div>
账号:<input type="text" v-model="form.account" />
</div>
<div>
密码:<input type="text" v-model="form.password" />
</div>
<div>
性别:
男:<input type="radio" v-model="form.gender" />
女:<input type="radio" v-model="form.gender" />
</div>
<div>
爱好:
爬山:<input type="checkbox" v-model="form.hobby" />
拍照:<input type="checkbox" v-model="form.hobby" />
画画:<input type="checkbox" v-model="form.hobby" />
</div>
<div>
地区:
<select v-model="form.city">
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<option value="guangzhou">广州</option>
<option value="shenzhen">深圳</option>
</select>
</div>
<div>
其他信息:<textarea v-model="form.other"></textarea>
</div>
<div>
<input type="checkbox" v-model="form.agree" />同意服务协议
</div>
<div>
<button @click="submit">提交</button>
</div>
</form>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data () {
return {
form: {}
}
},
methods: {
submit () {
console.log('表单数据', this.form)
}
}
}
</script>
v-model在内部为不同的输入元素使用不同的property并抛出不同的事件。
下面我们来看一下每一部分是怎么绑定的。
1. 输入框
下面我们看看账号密码这类的输入框是如何绑定的。
<div>
账号:<input type="text" v-model="form.account" />
</div>
<div>
密码:<input type="text" v-model="form.password" />
</div>
当我们在输入框中输入内容时,v-model会将我们的输入值绑定到data上。 此时v-model相当于是v-bind:value,而我们输入框的value当用户输入完会自动绑定到value上,无需手动给标签添加value属性。
效果如下:
2. 单选框Radio
对于单元框这类元素来说,v-model绑定的checked选项对应的value,如果不设置value的话,v-model绑定的将会是个null。
<div>
性别:
男:<input type="radio" v-model="form.gender" />
女:<input type="radio" v-model="form.gender" />
</div>
而且,不绑定value的话,选中其中一个最终所有的都会选中,达不到我们想要的单选效果。
效果如图所示:
添加value
<div>
性别:
男:<input type="radio" value="man" v-model="form.gender" />
女:<input type="radio" value="woman" v-model="form.gender" />
</div>
此时就能正常绑定data的值了,而且单选效果也能正常交互。
效果如下:
3. 复选框checkbox
复选框绑定的是checked选项
<div>
<input type="checkbox" v-model="form.agree" />同意服务协议
</div>
如果checbox是单选的时候,那么绑定的就是对应的checked
效果如下:
<div>
爱好:
爬山:<input type="checkbox" v-model="form.hobby" />
拍照:<input type="checkbox" v-model="form.hobby" />
画画:<input type="checkbox" v-model="form.hobby" />
</div>
如果checkbox是多选的时候,那么绑定的就是一个数组,内容是对应checked选中状态的value,也就是说多选状态下,必须定义value,如果不定义就是下面的效果:
所有的都选中,数据绑定失败
多选时候绑定value
<div>
爱好:
爬山:<input type="checkbox" value="climb" v-model="form.hobby" />
拍照:<input type="checkbox" value="photo" v-model="form.hobby" />
画画:<input type="checkbox" value="paint" v-model="form.hobby" />
</div>
data () {
return {
form: {
hobby: []
}
}
},
效果如下:
需要注意的是:多选绑定的时候一定要设置v-model的那个值为数组,否则它会默认绑定check的值
4. 下拉框select
下拉框也分为单选和多选两种情况。
4.1 单选
不设置value
<div>
地区:
<select v-model="form.city">
<option>北京</option>
<option>上海</option>
<option>广州</option>
<option>深圳</option>
</select>
</div>
此时绑定的是option里面的内容
效果如下:
设置value属性
<div>
地区:
<select v-model="form.city">
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<option value="guangzhou">广州</option>
<option value="shenzhen">深圳</option>
</select>
</div>
此时绑定的是option中设置的value属性。
效果如下:
4.2 多选
不设置value属性
<div>
地区:
<select v-model="form.city" multiple>
<option>北京</option>
<option>上海</option>
<option>广州</option>
<option>深圳</option>
</select>
</div>
多选和单选的情况相同,绑定的是option里面的内容,只是多选是一个数组,而单选是一个字符串。
效果如下:
设置value属性
<div>
地区:
<select v-model="form.city" multiple>
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<option value="guangzhou">广州</option>
<option value="shenzhen">深圳</option>
</select>
</div>
此时绑定的是一个数组,包含option中设置的value属性。
效果如下:
5. 多行文本输入框tetxarea
多行文本输入和普通input文本输入一样,都是绑定的value.
<div>
其他信息:<textarea v-model="form.other"></textarea>
</div>
效果如下:
小结:
v-model在内部为不同的输入元素使用不同的property并抛出不同的事件:
- text和textarea元素使用value property和input事件
- checkbox和radio使用checkbox property和change事件
- select字段将value作为prop并将change作为事件
具体总结下来:
若:<input type="text" />,则v-model收集的是value值,用户输入的就是value值
若:<input type="radio" />,则v-model收集的是value值,且要给标签设置value属性
若:<input type="checbox" />
- 没有设置input的value值,那么v-model收集的就是checked(布尔值,是否选中值)
- 设置input的value值,也分为两种情况: - v-model的初始值是非数组,那么收集的就是checked(布尔值,是否选中值) - v-model的初始值是数组,那么收集的就是value组成的数组
修饰符
之前我们介绍过事件是有修饰符的,其实v-model也是有修饰符的,一共有三种修饰符:.number, .lazy, .trim。
1. number修饰符
number修饰符能将字符串转成有效的数字,说到这个不得不提一下input的number类型,它们看起来功能相等,那到底有没有什么区别呢?
1.1 input的number类型
<div>
密码:<input type="number" v-model="form.password" />
</div>
这种情况下会限制非数字的输入,但是v-model绑定的值还是字符串类型
效果如下:
但是需要注意一下,科学计数符号E(e)是可以输入的,只是绑定的值变成”“, 效果如下:
1.2 number修饰符
<div>
密码:<input type="text" v-model.number="form.password" />
</div>
这种情况下,如果输入值包含数值,那么v-model绑定的就是number类型,而且会将字符串转成有效数值。如图所示。
如果输入不包含数值的字符串,那么v-model绑定的还是字符串类型,不会限制非数值的输入, 如图所示。
综上所述,一般会将input的number类型和number修饰符一起使用。
2. lazy修饰符
lazy修饰符可以让v-model在失去焦点之后再收集数据。从上面的例子可以看出,
- input输入框是在input时就开始收集数据
- radio和checkbox是在change时开始收集数据
- select也是在change时开始收集数据
如果在有的业务场景下,需要延迟再收集数据,那么就可以使用lazy修饰符
<div>
账号:<input type="text" v-model.lazy="form.account" />
</div>
这时候,只有在鼠标失去焦点之后,才会收集数据,data里面的数据才会发生变化
3. trim修饰符
trim修饰符是用来过滤字符串收尾的空格的。
<div>
账号:<input type="text" v-model="form.account" />
</div>
这种情况下,一旦输入空格,是会收集进去的,如图所示:
加上trim修饰符之后,收集的数据就会自动被过滤出去。
<div>
账号:<input type="text" v-model.trim="form.account" />
</div>
效果如下: