vue数据驱动实现原理
Vue 数据驱动实现原理
Vue 的数据驱动核心基于响应式系统,通过依赖收集和派发更新实现视图与数据的自动同步。
响应式数据劫持
Vue 2.x 使用 Object.defineProperty 对数据进行劫持,将数据对象的属性转换为 getter/setter:

function defineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
get() {
console.log('get:', key);
return val;
},
set(newVal) {
if (newVal === val) return;
console.log('set:', key);
val = newVal;
}
});
}
Vue 3.x 改用 Proxy 实现更全面的响应式支持:
const reactive = (target) => {
return new Proxy(target, {
get(target, key, receiver) {
const res = Reflect.get(target, key, receiver);
track(target, key); // 依赖收集
return res;
},
set(target, key, value, receiver) {
const res = Reflect.set(target, key, value, receiver);
trigger(target, key); // 派发更新
return res;
}
});
};
依赖收集与派发更新
每个响应式属性关联一个 Dep 实例,用于管理依赖(Watcher):

class Dep {
constructor() {
this.subs = new Set();
}
depend() {
if (currentWatcher) {
this.subs.add(currentWatcher);
}
}
notify() {
this.subs.forEach(watcher => watcher.update());
}
}
虚拟DOM与差异更新
数据变更后触发组件重新渲染,通过虚拟DOM进行高效更新:
// 简化版patch算法
function patch(oldVnode, newVnode) {
if (sameVnode(oldVnode, newVnode)) {
patchVnode(oldVnode, newVnode);
} else {
const parent = oldVnode.parentNode;
parent.replaceChild(createElm(newVnode), oldVnode);
}
}
异步更新队列
Vue 使用队列机制批量处理更新,通过 nextTick 实现异步更新:
let queue = [];
let waiting = false;
function queueWatcher(watcher) {
queue.push(watcher);
if (!waiting) {
waiting = true;
nextTick(flushQueue);
}
}
function flushQueue() {
queue.forEach(watcher => watcher.run());
queue = [];
waiting = false;
}
关键设计要点
- 响应式粒度:Vue 3 的 Proxy 可以实现属性级别的响应式,而 Vue 2 需要递归遍历对象
- 依赖追踪:通过全局变量记录当前 Watcher,实现动态依赖收集
- 更新优化:组件级更新结合虚拟DOM diff,避免不必要的 DOM 操作
- 异步机制:事件循环机制确保多次数据变更合并为单次渲染
这种设计使得开发者只需关注数据变化,Vue 自动处理视图更新,实现高效的数据驱动开发模式。






