前言
我们都知道v-model可以实现双向绑定,之前对v-model的了解还比较单一,今天来总结一下
单向绑定与双向绑定
单向绑定就是当我们用JavaScript代码更新Model时,View就会自动更新。
如果用户更新了View,Model的数据也自动被更新了,这种情况就是双向绑定。
首先 单向绑定 vue的响应式系统已经帮我们做了,那么我们如何在用户更新视图时更新数据呢?
对于文本输入框,在用户修改时,就会触发input事件,那么可以监听这个input事件,将这个输入框的值赋值到对应的数据
1 | <input type='text' :value="value" @input="value = $event.target.value"/> | 
v-model是个语法糖
以上我们已经实现了双向绑定 用v-model刚好可以替代这种复杂的语法
1 | <input type='text' v-model="value" /> | 
哈哈,简洁了不少
其他元素上的v-model
v-model会根据控件类型自动选取正确的方法来更新元素
- text 和 textarea 元素使用 value property 和 input 事件;
 - checkbox 和 radio 使用 checked property 和 change 事件;
 - select 字段将 value 作为 prop 并将 change 作为事件。
 
具体参考 表单输入绑定
自定义组件实现v-model
当用在组件上时,v-model 则会这样:
1 | <custom-input  | 
2 |   :value="searchText"  | 
3 |   @input="searchText = $event"> | 
4 | </custom-input> | 
这里的$event表示子组件传回来的值
为了让它正常工作,这个组件内的<input>必须:
- 将其 value attribute 绑定到一个名叫 value 的 prop 上
 - 在其 input 事件被触发时,将新的值通过自定义的 input 事件抛出
 
1 | Vue.component('custom-input', { | 
2 |   props: ['value'], | 
3 |   template: ` | 
4 |     <input | 
5 |       v-bind:value="value" | 
6 |       v-on:input="$emit('input', $event.target.value)" | 
7 |     > | 
8 |   ` | 
9 | }) | 
现在 v-model 就应该可以在这个组件上完美地工作起来了:
1 | <custom-input v-model="searchText"></custom-input> | 
vue3的v-model
以上都是vue2的v-model vue3对v-model进行了一些改进
- 首先属性名任意 不一定要是value (这里以xxx举例)
 - 事件变成了update:xxx
 
那么vue3的v-model 对searchText属性进行双向绑定时就是
1 | <custom-input  | 
2 |   :xxx="searchText"  | 
3 |   @updae:xxx="searchText = $event"> | 
4 | </custom-input> | 
子组件接收xxx属性 并触发update:xxx事件
1 | Vue.component('custom-input', { | 
2 |   props: ['xxx'], | 
3 |   template: ` | 
4 |     <input | 
5 |       v-bind:value="xxx" | 
6 |       v-on:input="$emit('update:xxx', $event.target.value)" | 
7 |     > | 
8 |   ` | 
9 | }) | 
在父组件中使用v-model
1 | <custom-input v-model:xxx="searchText"></custom-input> | 
需要注意的是 vue3的v-model语法取代了.sync语法