怎么实现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 defineReactive(obj, key, val) { Object.defineProperty(obj, key, { get() { return val; }, set(newVal) { if (newVal !== val) { val = newVal; console.log(`属性 ${key} 更新为 ${newVal}`); } } }); } -
依赖收集与通知:结合发布-订阅模式,在属性变化时通知视图更新。

class Dep { constructor() { this.subscribers = []; } addSub(sub) { this.subscribers.push(sub); } notify() { this.subscribers.forEach(sub => sub.update()); } } -
监听输入事件:将数据变化同步到视图,反之亦然。
const input = document.querySelector('input'); input.addEventListener('input', (e) => { data.message = e.target.value; });
基于 Proxy(Vue 3 使用)
Proxy 可以直接监听整个对象,无需递归遍历属性:
const handler = {
get(target, key) {
return target[key];
},
set(target, key, value) {
target[key] = value;
console.log(`属性 ${key} 更新为 ${value}`);
return true;
}
};
const reactiveData = new Proxy(data, handler);
完整示例代码
<div id="app">
<input type="text" id="input">
<p id="display"></p>
</div>
<script>
const data = { message: '' };
const input = document.getElementById('input');
const display = document.getElementById('display');
// 数据劫持
const reactiveData = new Proxy(data, {
set(target, key, value) {
target[key] = value;
display.textContent = value; // 更新视图
return true;
}
});
// 监听输入事件
input.addEventListener('input', (e) => {
reactiveData.message = e.target.value;
});
</script>
注意事项
- Vue 2.x 使用
Object.defineProperty,需递归遍历对象属性。 - Vue 3 改用
Proxy,支持监听动态新增的属性和数组变化。 - 双向绑定的性能优化需注意避免过度触发更新(如防抖)。






