在Vue 3中,自定义Prop的双向绑定方式相比Vue 2发生了明显变化。Vue 2提供的.sync修饰符已被正式移除,取而代之的是支持参数的v-model语法。这种方式让父子组件之间多个Prop的双向同步变得更直观,也更符合Vue 3整体的设计思路。

为什么.sync被移除了
在Vue 2中,为了让子组件修改父组件传下来的Prop,我们常写类似<Child :title.sync="pageTitle" />的代码。其本质是被展开为传递Prop加监听update:title事件。Vue 3团队认为这种特殊修饰符增加了学习成本,于是将能力统一进v-model,通过v-model:propName的形式表达同样意图。
Vue 3中的v-model参数写法
在父组件里,你可以像下面这样使用带参数的v-model:
<template>
<UserCard v-model:name="userName" v-model:age="userAge" />
</template>
<script setup>
import { ref } from 'vue'
import UserCard from './UserCard.vue'
const userName = ref('张三')
const userAge = ref(20)
</script>
子组件需要通过声明对应的modelValue式Prop,并在修改时触发update事件:
<script setup>
const props = defineProps({
name: String,
age: Number
})
const emit = defineEmits(['update:name', 'update:age'])
function changeName() {
// 通知父组件修改name
emit('update:name', '李四')
}
function grow() {
emit('update:age', props.age + 1)
}
</script>
<template>
<div>
<p>姓名:{{ name }}</p>
<p>年龄:{{ age }}</p>
<button @click="changeName">改名字</button>
<button @click="grow">长一岁</button>
</div>
</template>
与Vue 2.sync写法的对照
如果你之前写过Vue 2,可以参考下面这张对照表,快速理解迁移方式:
| Vue 2写法 | Vue 3写法 |
|---|---|
| <Comp :value.sync="x" /> | <Comp v-model:value="x" /> |
| this.$emit('update:value', newVal) | emit('update:value', newVal) |
多个双向绑定的优势
使用v-model参数后,同一个组件上可以写多个双向绑定,例如v-model:name与v-model:visible,而不必像过去那样混用v-model和.sync。这让组件接口更清晰,维护起来也更方便。
小结
Vue 3用带参数的v-model取代了.sync修饰符,实现了更统一的自定义Prop双向绑定方案。只要记住子组件用update:xxx事件回传、父组件用v-model:xxx接收,就能轻松完成组件间的数据同步。