vue双向实现数据
Vue 双向数据绑定的实现原理
Vue 的双向数据绑定主要通过 v-model 指令实现,其核心是结合了数据劫持(Object.defineProperty 或 Proxy)和发布-订阅模式。以下是具体实现方式:
使用 v-model 指令
v-model 是语法糖,默认绑定 value 属性并监听 input 事件。例如在输入框中:
<input v-model="message">
等价于:
<input
:value="message"
@input="message = $event.target.value"
>
手动实现双向绑定
基于 Object.defineProperty
-
数据劫持
通过Object.defineProperty监听对象属性的读写:function observe(obj) { Object.keys(obj).forEach(key => { let value = obj[key]; Object.defineProperty(obj, key, { get() { return value; }, set(newVal) { value = newVal; console.log(`属性 ${key} 更新为 ${newVal}`); } }); }); } const data = { message: '' }; observe(data); -
结合 DOM 事件
手动绑定输入框的input事件和数据的更新:document.getElementById('input').addEventListener('input', (e) => { data.message = e.target.value; });
基于 Proxy(Vue 3 使用)
Proxy 可以监听整个对象而非单个属性:
const data = new Proxy({ message: '' }, {
get(target, key) {
return target[key];
},
set(target, key, value) {
target[key] = value;
console.log(`属性 ${key} 更新为 ${value}`);
return true;
}
});
自定义组件中的双向绑定
在自定义组件中,v-model 默认绑定 modelValue 并触发 update:modelValue 事件:
<CustomInput v-model="message" />
组件内部实现:
props: ['modelValue'],
emits: ['update:modelValue'],
template: `
<input
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
>
`
双向绑定的核心流程
-
数据变化驱动视图更新
通过响应式系统监听数据变化,触发虚拟 DOM 的重新渲染。 -
视图变化更新数据
监听表单元素的输入事件(如input、change),将最新值同步到数据层。
注意事项
- Vue 2 中使用
Object.defineProperty对数组和对象的部分操作无法监听,需通过Vue.set处理。 - Vue 3 改用
Proxy解决了上述限制,并提升了性能。







