📚前端面试题速记
Q18

v-model 的双向数据绑定是如何实现的?

速记答案(30 秒)

本质是 :value + @input 的语法糖。自定义组件默认用 modelValue prop + update:modelValue 事件。

📖 详细讲解

标准面试回答(推荐记住)

v-model 是语法糖,在原生表单元素上等价于 :value 加 @input 事件;在自定义组件上,默认绑定 modelValue prop 和 update:modelValue 事件。Vue 3 支持多个 v-model 和自定义修饰符。

v-model 的演进

原生元素:

  • <input v-model="text"> 编译为:
    <input :value="text" @input="text = $event.target.value">
  • 针对 checkbox, radio, select 会有特殊的属性和事件处理(checked/change)。
  • 针对输入法 (IME) 做了优化:在拼音输入未确认时不会触发 model 更新。

自定义组件:
Vue 2 -> Vue 3 的变化:

  • Prop: value -> modelValue
  • Event: input -> update:modelValue
  • 破坏性变更: 移除了 .sync 修饰符,统一合并到了 v-model 参数中(例如 v-model:title)。

多个 v-model

<UserName
  v-model:first-name="first"
  v-model:last-name="last"
/>

面试要点

  • 理解 v-model 的语法糖本质
  • 知道自定义组件的约定
  • 掌握多个 v-model 的用法

💻 代码示例

v-model 实现原理
<!-- 原生元素 -->
<input v-model="text" />
<!-- 等价于 -->
<input :value="text" @input="text = $event.target.value" />

<!-- 自定义组件 -->
<CustomInput v-model="text" />
<!-- 等价于 -->
<CustomInput :modelValue="text" @update:modelValue="text = $event" />

<!-- CustomInput.vue -->
<script setup>
const model = defineModel<string>()
// 或者
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
</script>

<template>
  <input
    :value="model"
    @input="model = $event.target.value"
  />
</template>
v-model 双向绑定演示(可交互)
🎨 效果预览