前言
本文主要根据官方文档中的自定义组件上的 v-model 一栏,阅读后加上自己的一些理解和例子的补充。因为在参阅Vue官方文档时,有一些内容作者没有加上例子配合解释(可能觉得太简单了),所以有些含糊不清,初学者不是很能理解,所以写了这个系列。在自己的理解上加上一些例子,希望能帮助你更好的理解。
什么是v-model?
本文核心是 v-model ,所以先让我们去了解下什么是 v-model 呢?借用官方文档对它的解释:
你可以用
v-model指令在表单<input>、<textarea>及<select>元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但v-model本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。
总的来说,他其实就是可以实现双向数据绑定的语法糖,用法如下:
<div id="demo">
<input type="text" v-model="value">
</div>
var vm=new Vue({
el:"#demo",
data:{
value:'2'
}
})
通过以上语句就可以实现 value 值和输入框输入值的双向绑定。
上文也提到 v-model 其实是一个语法糖,那他真正的实现是咋样的呢?如下所示:
<div id="demo">
<input type="text" :value='value' @input="value=$event.target.value">
</div>
可以看到 v-model 拆成了两步:
- 利用
v-bind将输入框的值绑定在value变量上。当value变量改变,输入框的值也会变,实现单向数据绑定。 - 利用输入框的
input方法,当输入框值发生变化时将值传给value变量。至此双向数据绑定也就完成了。
在自定义组件上使用v-model
在组件上使用 v-model 也如上文这么简单吗?让我们来试一试。
Vue.component('base-input',{
template: `
<input type="text" >
`
})
var vm=new Vue({
el:"#demo",
data:{
price:'2'
}
})
<div id="demo">
<base-input v-model="price"></base-input>
</div>
运行后的结果却是根本没有成功的双向绑定。为什么呢?首先让我们把v-model转换成真实的实现代码会更方便理解。
<div id="demo">
<base-input :value="price" @input="price=$event"></base-input>
</div>
- 很明显父组件已经把输入框的
value值绑定到price变量,但还不够,此时应该将value值通过props传递给子组件,实现了父组件的price变量到子组件的value值的单向绑定 - 以及当子组件输入框值发生改变时就要主动通知父组件去改变
price变量。
让我们试着改造下组件代码:
Vue.component('base-input',{
props:['value'],
template: `
<input type="text" :value="value" @input="$emit('input',$event.target.value)">
`
})
至此输入框类型的自定义组件的双向数据绑定才算完成了。
单选框、复选框等类型的自定义组件使用v-model
在上文基础上再补充条必要的知识:一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件。这个条件对于输入框文本域这种改变value值的控件用起来会得心应手,但对单选框复选框等value值不会随用户操作而改变的类型就不是那么友好了。例如复选框,他关注的应该是 checked 属性和 change 事件。如果我们直接用v-model而不进行额外操作,那么这个组件其实没有任何作用。那额外的操作是什么呢?先拉上一段组件代码。
Vue.component('base-checkbox', {
model:{
prop: 'checked',
event: 'change'
},
props:{
'checked':Boolean
},
template: `
<input
type="checkbox" :checked='checked' @change="$emit('change',$event.target.checked)"
>
`
})
<base-checkbox v-model="demoValue"></base-checkbox>
出现了陌生的一个选项:model。看看官方文档是怎么介绍的呢:
- 类型:
{ prop?: string, event?: string }
- 详细:允许一个自定义组件在使用
v-model时定制 prop 和 event。默认情况下,一个组件上的v-model会把value用作 prop 且把input用作 event,但是一些输入类型比如单选框和复选框按钮可能想使用valueprop 来达到不同的目的。使用model选项可以回避这些情况产生的冲突。
这正是我们所要解决的问题,他可以修改默认的 value 属性和 input 事件。根据你的需求自己定义,如本例用的是复选框它需要的是 checked 属性和 change 事件,所以我们在 model 选项里修改了这一行为。所以其实上面引用组件的真实代码如下:
<base-checkbox :checked="demoValue" @change="demoValue=$event"></base-checkbox>
小结
所以当我们在自定义组件上使用 v-model 时,需要明确它默认的 prop 和 event 分别是 value 和 input 。需要根据实际情况做出改变。了解 v-model 是利用 v-bind 和事件监听来实现双向数据绑定的语法糖。