在Vue中,我们可以使用v-bind实现单项的数据绑定,也就是通过父组件向子组件传入数据 ,但是反过来,子组件不可以修改父组件传递过来的数据 ,这也就是所谓的单向数据绑定。
而v-mode
l就实现了双向数据绑定,实际上它就是通过Vue提供的事件机制。即在子组件通过$emit()触发一个事件,在父组件使用v-on来监听对应的事件并修改相应的数据。
在Vue中将上面的处理简化为一个语法糖,即:<input type="text" v-model="name">
概况
- 语法糖
// Vue2
<son type="text" v-model(:value)="count"></son>
// Vue3
<son v-model(:modelValue)="count"></son>
- 语法糖本质
// Vue2
<son type="text" :value="count" @input="count= $event.target.value"></son>
// Vue3
<son :show='show' @update:show='show = $event'><son/>
Vue2中使用语法糖
- 父组件
// 父组件
<template>
// 简写(默认名称)
<Son v-model="count" />
// 完整写法
<son :value="count" @input="updateValue" />
// 简写(自定义名称):newNmae可不写
<Son v-model:newNmae="count" />
// 完整写法(自定义名称)
<son :newNmae="count" @setNewName="updateValue" />
</template>
- 子组件
<script>
export default {
name: '',
mixins: [],
// 自定义v-model的数据名称
model: {
prop: 'newName', // 默认是 value
event: 'setNewName', // 默认是input
},
// 自定义名称
props: {
newName: {
type: String,
required: true
}
},
// 默认名称
props: {
value: {
type: String,
required: true
}
},
components: {},
data() {
return {}
},
methods: {
methods: {
onclick(event) {
// 默认事件
this.$emit('input', event.target.value)
// 自定义事件
this.$emit('setNewName', event.target.value)
}
}
}
}
</script>
Vue3中使用语法糖
- 父组件
<template>
<son v-model(:modelValue)="count"></son>
<son :modelValue='count' @update:modelValue='changeCount'><son/>
<!-- 这种写法可以写多个 -->
<son v-model:show="show"></son>
<son :show='show' @update:show='show = $event'><son/>
</template>
- 子组件
defineProps<{
// 默认名称
modelValue: number
show: boolean
options: {
label: string
value: number | string
}[]
back?: () => void
}>()
const emit = defineEmits<{
// 默认事件
(e: 'update:modelValue', data: number): void
// 自定义事件
(e: 'update:show', data: boolean): void
}>()
const updateData = () => {
// 默认事件名称
emit('update:modelValue', 123)
// 自定义事件名称
emit('update:show',true)
}
</script>