一、v-model 的实现机制解析
1. 表单元素中的实现机制
v-model 的实现本质是通过 双向数据绑定语法糖 ,将 v-bind:value 与 v-on:input 组合封装。
html
<input v-model="message">
等价于以下代码:
html
<input
:value="message"
@input="message = $event.target.value"
>
• 数据 → 视图 :通过 v-bind:value 将数据绑定到表单的 value 属性(或 checked、selected 等属性)
• 视图 → 数据 :监听 input 事件(或其他适配事件),通过事件对象 $event.target.value 更新数据
二、 自定义组件中的实现机制
在自定义组件中,v-model 通过 props + 事件 的组合实现父子组件双向通信,且支持 多数据绑定(Vue 3 特性)。
1、父组件实现
通过 v-model:test_data 指定自定义 prop 名称,将父组件 data 变量绑定到子组件的 test_data prop
html
<template>
<ChildComponent v-model:test_data="data" />
</template>
<script>
import ChildComponent from "./ChildComponent"
const data = ref('aaa')
</script>
<style> </style>
2、子组件实现
• props 接收 :通过 test_data prop 接收父组件数据
• 事件触发 :通过 emit('update:test_data') 事件反向更新父组件数据
• 双向同步 :子组件修改数据后,父组件的 data 变量会自动更新
javascript
// 接收父组件传递的 prop
const props = defineProps({
test_data: {
type: String,
required: true
}
});
// 定义事件发射器
const emit = defineEmits(['update:test_data']);
// 数据更新逻辑
const handleChange = (str) => {
emit('update:test_data', str); // 触发自定义事件,告知父组件更新数据
}
三、 为什么定义emit事件为 update:xxx
update:xxx 是 Vue 的双向绑定约定语法 ,当父组件通过 v-model:test_data 绑定时:
-
自动映射:
父组件的
v-model:test_data="data"会被编译为:html<ChildComponent :test_data="data" @update:test_data="data = $event" />子组件的
emit('update:test_data', newValue)会触发父组件的数据更新。
四、v-model可以绑定多个
v-model支持 多字段扩展:
允许一个组件同时绑定多个独立字段(如 v-model:firstName 和 v-model:lastName)
html
<CustomInput
v-model:first-name="firstName"
v-model:last-name="lastName"
/>
(PS): 同时绑定多个独立数据流,需在子组件分别定义对应的 props 和 emit 事件
五、 注意事项
- 避免直接修改 prop
子组件应通过事件触发更新,而非直接修改父组件传递的 prop - 复杂数据结构处理
对象类型数据需使用v-model的深层绑定特性(Vue 3 新增) - 性能敏感场景
高频输入场景建议使用.lazy修饰符减少更新频率