首先来理解下 v-model
<input v-model="something">
是语法糖
<input
v-bind:value="something"
v-on:input="something = $event.target.value">
与组件一起使用时,简化为
<custom-input
:value="something"
@input="value => { something = value }">
</custom-input>
所以对于一个组件来说v-model
,它应该(这些可以在2.2.0+中配置):
1.接受value道具
2.用新值发出一个input事件
一个组件上的 v-model
默认会利用名为 value
的 prop 和名为 input
的事件,但是像单选框、复选框等类型的输入控件可能会将 value
特性用于不同的目。model
选项可以用来避免这样的冲突:
<template>
<input
type="checkbox"
v-bind:checked="checked"
v-on:change="$emit('change', $event.target.checked)"
>
</template>
<script>
export default {
name: 'base-checkbox',
model:{
prop: 'checked',
event: 'change'
},
props: {checked: Boolean}
}
现在在这个组件上使用 v-model 的时候:
<base-checkbox v-model="lovingVue"></base-checkbox>
这里的 lovingVue
的值将会传入这个名为 checked
的 prop。同时当 <base-checkbox>
触发一个 change
事件并附带一个新的值的时候,这个 lovingVue
的属性将会被更新。
以上是官网的基本的方法,弄懂以上的前提下,我们来继续看嵌套组件时怎么再封装一个v-model,我们新建一个组件
special-checkbox
里面包含上面的组件base-checkbox
,如何将子父组件的v-model打通
<template>
<base-checkbox v-model="newlovingVue"></base-checkbox>
</template>
<script>
export default {
name: 'special-checkbox ',
model:{
prop:'lovingVue',//要存在于proops
event:'change'//当组件的值发生改变时要emit的事件名
},
props: ['lovingVue'],
data:function(){
return{//要重新定义一个data,赋值为props中的值,因为组件时单数据流,不能直接修改props
newlovingVue:this.lovingVue
}
},
watch:{//这里检测data中的值,一旦发生变化就提交事件到父组件
newlovingVue:function(newVal,oldVal){
this.$emit('change',newVal)
}
}
}
</script>
现在使用这个二次封装的组件的时候
<special-checkbox v-model="lovingVue"></base-checkbox>