父子组件通信
父组件自定义方法接收数据;
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-model
prop 和事件默认名称已更改:- 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
绑定到modelValue
prop - 当原生的
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
,默认绑定value
prop值和input
事件,可通过model
属性改变默认绑定prop和事件,但只能绑定单一 prop 值; - 使用
v-bind
的.sync
修饰符,可绑定多个 prop 值,使用update:myPropName
事件;
Vue3:
- 废除了
model
属性、.sync
修饰符; v-model
默认绑定modelValue
prop值和update:modelValue
事件;v-model
可通过v-model:myPropName
绑定多个 prop 值;