标准答案
- Vue 2 默认 v-model 对组件使用 value 作为 prop,input 作为更新事件。组件可以通过 model 选项改成其它 prop 和 event。
- Vue 2 的 .sync 常用于 prop 的双向更新,本质是监听 update:propName 事件后更新父组件状态。
- Vue 3 默认 v-model 使用 modelValue 和 update:modelValue,写法更统一。
- Vue 3 支持多个 v-model,例如 v-model:title、v-model:visible,每个对应一个 prop 和 update 事件。
- 迁移时要检查组件库 API。Vue 2 的 value/input、visible.sync、model 选项,通常要改成 Vue 3 的 modelValue/update:modelValue 或具名 v-model。
题目解析
这题的关键是把 v-model 拆成 prop 和 event。双向绑定不是魔法,只是父组件传值、子组件发事件。
Vue 3 多 v-model 让复杂表单组件、弹窗组件和筛选组件的接口更清楚。
Vue 2 的 .sync 在 Vue 3 中不再作为主要写法,应该用具名 v-model 或显式事件表达。
代码示例
下面是 Vue 3 中默认 v-model 和具名 v-model 的组件接口。
Vue
<!-- BaseDialog.vue -->
<script setup lang="ts">
defineProps<{
visible: boolean
title: string
}>()
const emit = defineEmits<{
'update:visible': [value: boolean]
'update:title': [value: string]
}>()
</script>
<template>
<dialog :open="visible">
<input
:value="title"
@input="emit('update:title', ($event.target as HTMLInputElement).value)"
>
<button type="button" @click="emit('update:visible', false)">
关闭
</button>
</dialog>
</template>Vue
<BaseDialog
v-model:visible="dialogVisible"
v-model:title="dialogTitle"
/>常见误区
- 只会背 v-model,不知道它背后是 prop 和 update 事件。
- 迁移 Vue 2 组件时继续使用 value/input,导致父组件 v-model 不生效。
- 复杂组件只塞一个 modelValue,多个状态含义混在一起。