官网链接:自定义组件的 v-model
v-model相当于一个语法糖(简写)
<input v-model="value" type="text">
就相当于:
<input :value="value" @input="value=$event.target.value" type="text">
由上面代码可知:v-model 默认会利用名为 value 的属性 和名为 input 的事件,但是如果我们想用其他属性或事件呢?例如:
<input :checkd="value" @change="value=$event.target.checkd" type="check">
那么这时候我们就要自定义v-model,通过父子组件互相传值的形式。
子组件:
<template>
<div>
<input type="checkbox" @change="handleCheck" :checked="checkedMsg"></input>
</div>
</template>
<script>
export default {
props: ['checkedMsg'],
methods: {
handleCheck(e) {
this.$emit('checkChange',e.target.checked)
}
}
}
</script>
可进一步简写为:
<template>
<div>
<input type="checkbox" @change="$emit('checkChange',$event.target.checked)" :checked="checkedMsg"></input>
</div>
</template>
<script>
export default {
props: ['checkedMsg'],
}
</script>
父组件:
<template>
<div class="home">
<h3>{{checkVal}}</h3>
<ModelText :checkedMsg="checkVal" @checkChange="getChecked"/>
</div>
</template>
<script>
import ModelText from '@/components/ModelText'
export default {
components: {
ModelText
},
data() {
return {
checkVal: false,
}
},
methods: {
getChecked(data) {
this.checkVal = data;
}
}
}
</script>
可进一步简写为:
<template>
<div class="home">
<h3>{{checkVal}}</h3>
<ModelText :checkedMsg="checkVal" @checkChange="checkVal = $event"/>
</div>
</template>
<script>
import ModelText from '@/components/ModelText'
export default {
components: {
ModelText
},
data() {
return {
checkVal: false,
}
},
}
</script>
此外还可直接使用 v-model 语法糖:
子组件:
<template>
<div>
<input type="checkbox" @change="$emit('checkChange',$event.target.checked)" :checked="checkedMsg"></input>
</div>
</template>
<script>
export default {
props: ['checkedMsg'],
model: {
prop: 'checkedMsg',
event: 'checkChange'
},
}
</script>
父组件:
<template>
<div class="home">
<h3>{{checkVal}}</h3>
<ModelText v-model="checkVal"/>
</div>
</template>
<script>
import ModelText from '@/components/ModelText'
export default {
components: {
ModelText
},
data() {
return {
checkVal: false,
}
},
}
</script>
这样就实现v-model自定义组件,但是看到这里肯定有个疑问,
子组件中直接这样写就可以实现双向绑定了啊:
<template>
<div>
<p>{{checkedMsg}}</p>
<input type="checkbox" @change="checkedMsg = $event.target.checked" :checked="checkedMsg"></input>
</div>
</template>
<script>
export default {
data() {
return {
checkedMsg: false,
}
}
}
</script>
这样是可以实现,但是咱们初衷是自定义v-model,假如多处需要check标签的双向绑定时,自定义v-model在每次用的时候只需要引入同一个子组件就方便多了。