一、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
修饰符减少更新频率