vue双向数据实现
Vue 双向数据绑定的实现原理
Vue 的双向数据绑定主要通过 v-model 指令实现,其核心是基于数据劫持和发布-订阅模式。
数据劫持(响应式原理)
Vue 使用 Object.defineProperty(Vue 2)或 Proxy(Vue 3)监听对象属性的变化。当数据变化时,触发 setter 通知依赖更新。
// Vue 2 的响应式实现示例
const data = { value: '' };
Object.defineProperty(data, 'value', {
get() { return this._value; },
set(newVal) {
this._value = newVal;
console.log('数据更新了'); // 触发视图更新
}
});
模板编译
Vue 将模板编译为渲染函数,解析 v-model 指令时:

- 为元素绑定
input事件(如文本框) - 将数据值赋给元素的
value属性
v-model 的实现
v-model 是语法糖,等价于手动绑定 value 和 input 事件:
<input v-model="message">
<!-- 等价于 -->
<input
:value="message"
@input="message = $event.target.value">
自定义组件的双向绑定
在自定义组件中实现 v-model 需声明 model 选项(Vue 2)或使用 v-model 参数(Vue 3):

Vue 2 实现
export default {
model: {
prop: 'value', // 绑定的属性名
event: 'input' // 触发的事件名
},
props: ['value'],
methods: {
updateValue(newVal) {
this.$emit('input', newVal);
}
}
}
Vue 3 实现
Vue 3 支持多个 v-model 绑定:
export default {
props: ['modelValue'],
emits: ['update:modelValue'],
methods: {
updateValue(newVal) {
this.$emit('update:modelValue', newVal);
}
}
}
修饰符处理
v-model 支持修饰符如 .lazy、.number:
.lazy将input事件改为change事件.number自动将输入转为数值类型
<input v-model.lazy="message">
<input v-model.number="count">
与其他技术的对比
- React:通过受控组件手动实现双向绑定
- Angular:使用
[(ngModel)]类似机制 - Svelte:编译时生成双向绑定代码
通过以上机制,Vue 实现了高效的双向数据绑定,简化了表单处理逻辑。






