详解v-model:语法糖

v-model:语法糖

 vue的v-model为表单的完成提供了极大的便利,可以进行数据绑定,例如将input框的值和span值绑定,只要重新输入显示值会立即更改。下面我们来分析这一命令是如何实现的。在官方文档中解释这一名令实际仅是一个语法糖。
那么首先我们来看看语法糖的概念:

语法糖:指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。通常来说使用语法糖能够增加程序的可读性,从而减少程序代码出错的机会。

1. v-model用在input元素上时

1
<input v-model="something" />
1
<input v-bind:value="something" v-on:input="something= $event.target.value" />

 第一行的代码其实只是第二行的语法糖。然后第二行代码还能简写成这样:

1
<input :value="something" @input="something= $event.target.value" />

 要理解这行代码,首先你要知道 input 元素本身有个 oninput 事件,这是 HTML5 新增加的,类似 onchange ,每当输入框内容发生变化,就会触发 oninput ,把最新的value传递给 something。

 也就是v-model=”something”则表示将value值绑定在something上,当值发生改变时触发绑定的oninput事件。oninput事件绑定的函数是将触发oninput事件的目标(该input)的value值赋值给something这个变量。

 我们仔细观察语法糖和原始语法那两行代码,可以得出一个结论:
 在给input元素添加 v-model 属性时,将value值绑定在something变量上,当值发生改变时触发绑定的oninput事件,oninput事件绑定的函数是将触发oninput事件的目标的value值赋值给something这个变量。

2. v-model 用在组件上时

 v-model 不仅仅能在 input上用,在组件上也能使用。
从v-model的实现原理,我们知道要在组件中使用时,它相当于下面的简写:

1
<custon-input v-bind:value="something" v-on:input="something=arguments[0]"></custom-input>

所以要让组件的v-model生效,它应该:

  • 1. 接受一个value属性
  • 2. 在有新的值时触发input事件

 代码如下:自定义一个不能输入负数的input框

  • custon-input组件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<template>
<div>
<input :value="value" @input="updateValue($event.target.value)"/>
</div>
</template>
<script>
export default {
name: 'CustonInput',
props: ['value'],
data () {
return {
checkboxValue: false
}
},
methods:{
updateValue(value){
if (value < 0) {
this.$emit("input", 0) //值小于0时候,赋值为0
}else{
this.$emit("input", value) //触发input事件,父组件接收input事件
}
}
}
}
</script>
  • //父组件中使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<template>
<div>
<custon-input v-model="custonValue"></custon-input>
</div>
</template>

<script>
import CustonInput from './CustonInput.vue'
export default {
name: 'Home',
components: {CustonInput},
data () {
return {
custonValue: '10', //给一个默认值
}
},
methods:{
receiveData(data){
console.log(data); //I am from child
}
},
watch:{
custonValue (val) {
console.log(val)
}
}
}
</script>

3. v-model 的缺点和解决办法

 在创建类似复选框或者单选框的常见组件时,v-model就不好用了。
 Vue 1.x版本中:checkbox使用v-model不起效

1
<input type="checkbox" v-model="sth" />

 v-model 给我们提供好了 value 属性和 oninput 事件,但是,我们需要的不是 value 属性,而是 checked 属性,并且当你点击这个单选框的时候不会触发 oninput 事件,它只会触发 onchange 事件。这就尴尬了

 因为 v-model 只是用到了 input 元素上,所以这种情况好解决:

1
<input type="checkbox" :checked="status" @change="status = $event.target.checked" />

 Vue 2.x版本中,可以使用v-model实现checkbox的双向绑定。

1
<input type="checkbox" v-model="sth" />

 在使用checkbox中遇到的坑,详情见《vue checkbox使用v-model和@click遇到的坑》


作者: Jessy Hong