关于v-model的使用这件事
v-bind
v-bind
可以把标签的某个属性和vue组件的某个变量**单向绑定**起来,举个栗子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue-form</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="container"> <label>input <input type="text" v-bind:value="text"> </label> <p>{{ text }}</p> </div> </body> <script> const vm1 = new Vue({ el: '#container', data: { text: 'nothing to show' } }); </script> </html>
|
效果:
如果我们在控制台去改变text
的值,新的值会立即渲染到页面上:
但是反过来,如果在输入框改变input的value
,text
并不会发生改变:
这就是所谓的单向绑定。那么如何实现双向绑定呢?
v-model
v-model可以用来实现双向绑定。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue-form</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="container"> <label>input <input type="text" v-model="text"> </label> <p>{{ text }}</p> </div> </body> <script> const vm1 = new Vue({ el: '#container', data: { text: 'nothing to show' } }); </script> </html>
|
初始效果:
改变输入框的值:
可以到变量text
和input
的value
已经牢牢地绑定在一起,不求同年同月同日生,但求同年同月同日死。
v-model到底做了些什么呢?
v-model
本质是语法糖(没有v-model
的时候可以通过更复杂一些的方法实现v-model
的功能),他帮助我们做了两件事。
第一件事
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue-form</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="container"> <label>input <input type="text" v-bind:value="text"> </label> <p>{{ text }}</p> </div> </body> <script> const vm1 = new Vue({ el: '#container', data: { text: 'nothing to show' } }); </script> </html>
|
用v-bind
将标签的value
和指定变量单向绑定。
第二件事
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue-form</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="container"> <label>input <input type="text" v-bind:value="text" v-on:input="text = $event.target.value"> </label> <p>{{ text }}</p> </div> </body> <script> const vm1 = new Vue({ el: '#container', data: { text: 'nothing to show' } }); </script> </html>
|
在第一步的基础上,用v-on监听input事件,进而通过JavaScript代码修改变量text的值,从而实现双向绑定。
在自定义组件上使用v-model
可见,使用v-model
进行双向绑定很方便,但是,并非在任何情况下都可以直接使用v-model
。
一个组件上的 v-model
默认会利用名为 value
的 prop 和名为 input
的事件,但是像单选框、复选框等类型的输入控件可能会将 value
attribute 用于不同的目的。比如type=checkbox
类型的input
,应该去利用它的checked
属性和change
事件,这时就需要我们去使用model
选项。
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 29 30 31 32 33
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue-form</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="container"> <base-checkbox v-model="choice"></base-checkbox> <p>{{ choice }}</p> </div> </body> <script> Vue.component('base-checkbox', { model: { prop: 'checked', event: 'change' }, props: { checked: Boolean }, template: `<input type="checkbox" v-bind:checked="checked" v-on:change="$emit('change',$event.target.checked)">` }); const vm1 = new Vue({ el: '#container', data: { choice: false } }); </script> </html>
|
这样做即可实现双向绑定。
效果:

$emit(event,args)可以去触发一个事件并传入参数,如果有所迷惑,可以看下面的栗子:
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 29 30 31 32 33 34 35 36 37 38 39 40
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue-form</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="container"> <base-checkbox v-bind:checked="choice" v-on:change="sync"></base-checkbox> <p>{{ choice }}</p> </div> </body> <script> Vue.component('base-checkbox', { model: { prop: 'checked', event: 'change' }, props: { checked: Boolean }, template: `<input type="checkbox" v-bind:checked="checked" v-on:change="$emit('change', $event.target.checked)">` });
const vm1 = new Vue({ el: '#container', data: { choice: false }, methods: { sync: function (checked) { console.log(checked); this.choice = checked; } } }); </script> </html>
|
两种版本的效果完全一样,但通过对比,我们可以体会到v-model
帮我们做了些什么。