Vue3 组件 v-model 与 Vue2 有何变化?
先理解原理和示例,再练习完整口述与追问。
回答要点
默认约定为 modelValue / update:modelValue,支持带参数的多个模型绑定。Vue3.4+ 可用 defineModel 简化声明;底层仍是 prop 和更新事件,需明确默认值与父级状态同步。
原理拆解
Vue3 自定义组件默认使用 modelValue 与 update:modelValue,带参数模型如 v-model:title 对应 title 与 update:title,可以清晰表达多个独立值。defineModel 是较新 Vue3 的编译宏,用更短写法表达同样契约。模型仍基于父传入与子通知,子直接修改任意 prop 并不是双向绑定的推荐实现。
示例与推演
<script setup>
const props = defineProps({ modelValue: String })
const emit = defineEmits(['update:modelValue'])
</script>
<template>
<input :value="props.modelValue" @input="emit('update:modelValue', $event.target.value)">
</template>
父级 v-model 可监听子事件更新自己的状态;修饰符若用于自定义组件,转换含义需要由组件契约实现。
易错点
迁移时 Vue2 value/input 与 Vue3 modelValue/update:modelValue 不可混用。defineModel 的默认值可能与父未传值产生不同初始状态,不能忽略同步边界。
参考回答可直接练习口述
Vue3 组件默认 v-model 由 modelValue 输入与 update:modelValue 事件组成;带参数时例如 v-model:visible 使用 visible 和 update:visible,因此可以在一个组件上建立多个独立模型。Vue3.4+ 的 defineModel 简化了这组声明,读写得到的模型 ref 会按约定与父级同步,数据所有权和默认值仍要设计清楚。
面试官可能继续问追问与完整解答展开收起
追问
如何做 v-model:visible?如何实现修饰符?只设子级默认值为何可能与父级产生状态差异?Vue3 官方组件 v-model
追问回答
v-model:visible 的子级接口就是 visible prop 和 update:visible 事件,或 defineModel("visible")。修饰符可以读取相应模型修饰符并在设置时转换。若子组件有默认值而父值仍为 undefined,初始两端可能不同,最好由父级提供明确初值或定义同步规则。