自定义组件的 v-model 和 .sync 修饰符其实本质上都是vue的语法糖,用于实现父子组件的“数据”双向绑定
v-model只是一个语法糖,等于:value+@input,真正的实现靠的还是: v-bind:绑定响应式数据,触发 input 事件并传递数据 (核心和重点)
在vue3中,v-model
可作用于自定义组件,当其作用于自定义组件时,默认情况下,它会生成一个modelValue
属性和onUpdate:modelValue
事件。
总结:
父组件通过v-model绑定一个变量传给子组件
子组件通过props['value']接收
子组件通过$emit('input',XX)去改变父组件中v-model绑定的变量
例子如下:
<!--子组件-->
<template>
<div>
<div v-show="isShow">{{value}}</div>
<Button @click="hide">隐藏</Button>
</div>
</template>
<script>
export default {
props:['value'],
data() {
return {
isShow: this.value
}
},
methods: {
hide() {
this.isShow = false,
$emit('input',false)
}
}
}
</script>
<!--父组件-->
<template>
<AddModal ref="addModal" v-model="showModal" />
<Button @click="showModal">显示</Button>
</template>
<script>
import AddModal from '../addModal';
export default {
components: {
AddModal
},
data() {
return {
showModal: false
}
},
methods: {
showModal() {
this.showMal = true
}
},
}
</script>
.sync修饰符:
首先我们知道,父组件通过绑定属性的方式向子组件传值,而在子组件中可以通过$emit向父组件通信,通过这种间接的方式改变父组件的data,从而实现子组件改变props的值。比如向下边这这样:
子组件使用$emit向父组件发送事件:
this.$emit('update:title', newTitle)
父组件监听这个事件并更新一个本地的数据title:
<text-document
:title="title"
@update:title="val => title = val"
></text-document>
为了方便这种写法,vue提供了.sync修饰符,说白了就是一种简写的方式,我们可以将其当作是一种语法糖,比如v-on: click可以简写为@click。而上边父组件的这种写法,换成sync的方式就像下边这样:
<text-document
:title.sync="title"
></text-document>