vue双向绑定原理实现
Vue 双向绑定原理实现
Vue 的双向绑定核心是通过数据劫持结合发布-订阅模式实现的,主要依赖 Object.defineProperty(Vue 2.x)或 Proxy(Vue 3.x)来监听数据变化。
数据劫持
Vue 2.x 使用 Object.defineProperty 劫持对象的属性,通过 getter 和 setter 监听数据变化。

function defineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
get() {
console.log(`读取 ${key}: ${val}`);
return val;
},
set(newVal) {
if (newVal !== val) {
console.log(`设置 ${key}: ${newVal}`);
val = newVal;
}
}
});
}
const data = {};
defineReactive(data, 'message', 'Hello Vue');
data.message; // 读取 message: Hello Vue
data.message = 'Updated'; // 设置 message: Updated
Vue 3.x 使用 Proxy 代理整个对象,可以监听新增或删除的属性。

function reactive(obj) {
return new Proxy(obj, {
get(target, key) {
console.log(`读取 ${key}: ${target[key]}`);
return target[key];
},
set(target, key, value) {
if (target[key] !== value) {
console.log(`设置 ${key}: ${value}`);
target[key] = value;
}
return true;
}
});
}
const data = reactive({ message: 'Hello Vue' });
data.message; // 读取 message: Hello Vue
data.message = 'Updated'; // 设置 message: Updated
依赖收集
Vue 通过依赖收集跟踪哪些数据属性被哪些组件或计算属性使用。当数据变化时,通知所有依赖进行更新。
class Dep {
constructor() {
this.subscribers = new Set();
}
depend() {
if (activeEffect) {
this.subscribers.add(activeEffect);
}
}
notify() {
this.subscribers.forEach(effect => effect());
}
}
let activeEffect = null;
function watchEffect(effect) {
activeEffect = effect;
effect();
activeEffect = null;
}
const dep = new Dep();
watchEffect(() => {
dep.depend();
console.log('Effect run');
});
dep.notify(); // 输出 "Effect run"
实现双向绑定
结合数据劫持和依赖收集,可以实现简单的双向绑定。
<input id="input" type="text">
<div id="display"></div>
<script>
const input = document.getElementById('input');
const display = document.getElementById('display');
const data = reactive({ text: '' });
watchEffect(() => {
display.textContent = data.text;
});
input.addEventListener('input', (e) => {
data.text = e.target.value;
});
</script>
完整流程
- 初始化时通过
Object.defineProperty或Proxy劫持数据。 - 在
getter中收集依赖(如模板中的{{text}}或计算属性)。 - 在
setter中触发依赖更新(如重新渲染组件或计算属性)。 - 通过
v-model指令将表单输入与数据属性绑定,实现双向同步。
这种机制确保了数据变化时视图自动更新,视图输入变化时数据自动同步。






