父子组件通信
父组件自定义方法接收数据;
1 | <template> |
MyInput 子组件 emit 自定义事件
1 | <template> |
以上通过父子组件通信的方式一样能双向绑定数据,但需要通过父组件自定义事件接收数据,能不能像表单一样通过 v-model 来实现自定义组件的双向绑定呢?
Vue2+
v-model 的本质
1 | <input type="text" v-model="myValue" /> |
本质上等价于
1 | <input type="text" :value="myValue" @input="myValue = $event.target.value" /> |
而当使用在一个组件上时,v-model 会被展开为如下的形式:
1 | <my-input :value="myValue" @input="myValue = $event"/> |
v-model 双向绑定
默认情况下,一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件。
MyInput组件
1 | <template> |
调用 MyInput 组件
1 | <my-input v-model="myValue" /> |
以上即可通过 v-model 实现双向绑定,但是像单选框、复选框等类型的输入控件可能会将 value attribute 用于不同的目的。model 选项可以用来避免这样的冲突:
1 | <template> |
现在在这个组件上使用 v-model 的时候:
1 | <my-input v-model="val"/> |
这里的 val 的值将会传入这个名为 checked 的 prop。同时当 MyInput 组件触发一个 change 事件并附带一个新的值的时候,这个 val 的 property 将会被更新。
.sync 的本质
1 | <my-component :title.sync="title" /> |
等价于
1 | <my-component :title="title" @update:title="title = $event" /> |
注意带有
.sync修饰符的v-bind不能和表达式一起使用 (例如v-bind:title.sync=”title + ‘!’”是无效的)。取而代之的是,你只能提供你想要绑定的property名,类似v-model。
.sync 双向绑定
MyDialog 组件
1 | <template> |
调用 MyDialog 组件
1 | <my-dialog :show.sync="dialogShow"> |
Vue3 中的变化
- 用于自定义组件时,
v-modelprop 和事件默认名称已更改:- prop:
value->modelValue; - 事件:
input->update:modelValue;
- prop:
v-bind的.sync修饰符和组件的model选项已移除,可在v-model上加一个参数代替;- 现在可以在同一个组件上使用多个
v-model绑定;
v-model
Vue3 中 v-model 使用在组件中不再是默认利用名为 value 的 prop 和名为 input 的事件了。当使用在一个组件上时,v-model 会被展开为如下的形式:
1 | <my-input v-model="myValue"> |
<my-input> 组件内部需要做两件事:
- 将内部原生
<input>元素的 valueattribute绑定到modelValueprop - 当原生的
input事件触发时,触发一个携带了新值的update:modelValue自定义事件
1 | <!-- MyInput.vue --> |
利用 computed 实现双向绑定
在组件内实现 v-model 的方式是使用一个可写的,同时具有 getter 和 setter 的 computed 属性。get 方法需返回 modelValue prop,而 set 方法需触发相应的事件:
1 | <!-- MyInput.vue --> |
绑定多个 v-model
1 | <ChildComponent v-model:title="pageTitle" v-model:content="pageContent" /> |
总结
自定义组件的双向绑定,本质上都是通过父子组件双向通信的方式,只是 v-model 和 .sync 修饰符提供了简写方式的语法糖,可以不用父组件提供接收参数事件。
Vue2:
- 使用
v-model,默认绑定valueprop值和input事件,可通过model属性改变默认绑定prop和事件,但只能绑定单一 prop 值; - 使用
v-bind的.sync修饰符,可绑定多个 prop 值,使用update:myPropName事件;
Vue3:
- 废除了
model属性、.sync修饰符; v-model默认绑定modelValueprop值和update:modelValue事件;v-model可通过v-model:myPropName绑定多个 prop 值;



