Vue3 高频题 · 第 7 题
主问题
问:Vue3 中 v-model 的工作原理是什么?为什么 Vue3 支持多个 v-model?如何在子组件中实现?
一、核心回答(面试官满意版)
1)Vue3 的 v-model 实际上是 props + emit 的语法糖
在父组件中:
ini
<Child v-model="username" />
等价于:
ini
<Child
:modelValue="username"
@update:modelValue="val => username = val"
/>
也就是说:
- props:modelValue
- emit:update:modelValue
Vue3 统一了 v-model 的名字,让逻辑更一致、更可扩展。
2)支持多个 v-model(Vue2 不支持)
Vue2 只有固定的一个 value 和事件 input
Vue3 允许:
ini
<Child
v-model:title="title"
v-model:content="content"
/>
等价于:
ini
<Child
:title="title"
@update:title="val => title = val"
:content="content"
@update:content="val => content = val"
/>
二、在子组件中如何实现?(最重要)
子组件写法(script setup)
xml
<script setup>
const props = defineProps({
modelValue: String,
title: String,
content: String
})
const emit = defineEmits([
'update:modelValue',
'update:title',
'update:content'
])
function changeValue(e) {
emit('update:modelValue', e.target.value)
}
</script>
<template>
<input :value="modelValue" @input="changeValue" />
</template>
三、Vue3 v-model 的功能增强(面试官喜欢听)
① v-model 可以做双向绑定(依旧保持 Vue2 的能力)
② v-model 不再绑定固定的 value / input
可以绑定任何属性名,如:
ini
v-model:checked="isChecked"
v-model:current-page="page"
③ 修饰符也可以自定义(Vue3 的新特性)
ini
<Child v-model.trim="value" />
子组件可接受:
javascript
defineProps({
modelValue: String,
modelModifiers: Object
})
四、典型示例:自定义 Input 组件
父组件
ini
<CustomInput v-model="msg" />
子组件
xml
<script setup>
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
function onInput(e) {
emit('update:modelValue', e.target.value)
}
</script>
<template>
<input :value="modelValue" @input="onInput">
</template>
五、深度追问(面试官常考)
追问 1:v-model 在 template 中为什么不需要写 .value?
因为 Vue 会自动ref 解包(unwrap) 。
模板中自动把 ref.value 转成普通值展示。
追问 2:v-model 为什么要用事件 update:modelValue 而不是 input?
为了避免名称冲突,并且可以支持多个 v-model。
如果使用 input/value 就不可能做多字段绑定。
追问 3:可以把 v-model 的属性名改成别的吗?
可以!
例如:
ini
<Child v-model:visible="showDialog" />
子组件 props:
css
defineProps(['visible'])
defineEmits(['update:visible'])
追问 4:多个 v-model 会影响性能吗?
不会。
它只是更多的 props 与 emit,没有额外开销。
六、killer 问题(高分必杀)
❓ "v-model 的原理和 provide/inject 有什么关系?"
答:没有关系!
v-model 只是父子之间最常用的"单属性双向绑定",
provide/inject 是跨层级通信,两者的作用和原理完全不同。
能回答清楚这一点,说明你能区分 Vue3 的通信场景 → 加分。
七、最终总结(1 分钟背诵版)
Vue3 的 v-model =
modelValue+update:modelValue的语法糖。Vue3 可以绑定多个 v-model,因为事件名可动态命名。
子组件必须:
- 定义对应 props
- 定义对应 emit
- 事件里 emit 回去
v-model 的核心价值是规范、统一、支持多字段绑定,自定义组件必考点。