vue双向绑定实现简单
Vue 双向绑定的实现原理
Vue 的双向绑定主要通过 v-model 指令实现,其核心是结合了数据劫持(Object.defineProperty 或 Proxy)和发布-订阅模式。以下是简化版的实现逻辑:
数据劫持
通过 Object.defineProperty 监听对象属性的变化:
function defineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
get() {
return val;
},
set(newVal) {
if (newVal === val) return;
val = newVal;
// 触发更新
dep.notify();
}
});
}
依赖收集(Dep 类)
class Dep {
constructor() {
this.subs = [];
}
addSub(sub) {
this.subs.push(sub);
}
notify() {
this.subs.forEach(sub => sub.update());
}
}
观察者(Watcher 类)
class Watcher {
constructor(vm, key, updateFn) {
this.vm = vm;
this.key = key;
this.updateFn = updateFn;
Dep.target = this;
this.vm[this.key]; // 触发 getter 收集依赖
Dep.target = null;
}
update() {
this.updateFn.call(this.vm, this.vm[this.key]);
}
}
简单实现示例
以下是一个极简的双向绑定 Demo:
<input id="input" type="text">
<p id="text"></p>
<script>
const data = { value: '' };
const input = document.getElementById('input');
const text = document.getElementById('text');
// 数据劫持
Object.defineProperty(data, 'value', {
get() {
return this._value;
},
set(newVal) {
this._value = newVal;
text.innerText = newVal; // 更新视图
}
});
// 视图 -> 数据
input.addEventListener('input', (e) => {
data.value = e.target.value;
});
// 初始化
data.value = 'Hello Vue';
input.value = data.value;
</script>
现代实现(Proxy 替代)
Vue 3 使用 Proxy 实现更高效的数据监听:

const data = new Proxy({ value: '' }, {
set(target, key, value) {
target[key] = value;
text.innerText = value;
return true;
}
});
关键点
- 数据驱动视图:通过数据变化自动更新 DOM。
- 视图影响数据:通过事件监听(如
input)修改数据。 - 性能优化:Vue 实际实现中会使用虚拟 DOM 和异步更新策略。






