vue vm实现原理
Vue VM 实现原理
Vue.js 的 ViewModel(VM)实现原理主要基于数据劫持和发布-订阅模式,通过响应式系统将数据与视图动态绑定。以下是核心实现机制:
响应式数据劫持
Vue 使用 Object.defineProperty(Vue 2)或 Proxy(Vue 3)劫持数据对象的属性访问和修改。当数据变化时,触发依赖更新。
Vue 2 示例:

function defineReactive(obj, key, val) {
const dep = new Dep(); // 依赖收集器
Object.defineProperty(obj, key, {
get() {
if (Dep.target) dep.depend(); // 收集依赖
return val;
},
set(newVal) {
if (newVal === val) return;
val = newVal;
dep.notify(); // 触发更新
}
});
}
Vue 3 使用 Proxy:
const reactive = (target) => {
return new Proxy(target, {
get(target, key, receiver) {
track(target, key); // 依赖收集
return Reflect.get(target, key, receiver);
},
set(target, key, value, receiver) {
Reflect.set(target, key, value, receiver);
trigger(target, key); // 触发更新
return true;
}
});
};
依赖收集与派发更新
- Dep 类:管理依赖(Watcher 实例),通过
depend()收集依赖,notify()通知更新。 - Watcher 类:作为观察者,在数据变化时执行回调(如更新视图)。
class Dep {
constructor() {
this.subs = [];
}
depend() {
if (Dep.target) this.subs.push(Dep.target);
}
notify() {
this.subs.forEach(watcher => watcher.update());
}
}
Dep.target = null; // 全局当前 Watcher
虚拟 DOM 与 Diff 算法
Vue 通过虚拟 DOM 减少直接操作真实 DOM 的开销。当数据变化时,生成新的 VNode,通过 Diff 算法比对差异并局部更新。

关键步骤:
- Patch:对比新旧 VNode,更新差异部分。
- Diff 优化:同级比较,通过
key复用节点。
function patch(oldVnode, newVnode) {
if (sameVnode(oldVnode, newVnode)) {
patchVnode(oldVnode, newVnode); // 精细化比对
} else {
replaceNode(oldVnode, newVnode); // 替换整个节点
}
}
模板编译
Vue 将模板编译为渲染函数,生成虚拟 DOM:
- 解析:将模板转换为 AST(抽象语法树)。
- 优化:标记静态节点,避免重复渲染。
- 生成代码:将 AST 转换为可执行的渲染函数。
// 示例编译结果
function render() {
return _c('div', { attrs: { id: 'app' } }, [_v('Hello World')]);
}
组件化机制
每个 Vue 组件实例对应一个 ViewModel,通过以下方式实现独立更新:
- 父子通信:
props向下传递,$emit向上触发事件。 - 依赖注入:
provide/inject跨层级数据共享。
Vue.component('child', {
props: ['message'],
template: `<div>{{ message }}</div>`
});
总结
Vue VM 的核心是通过响应式数据绑定、依赖管理、虚拟 DOM 和模板编译,实现数据与视图的自动同步。Vue 3 的改进(如 Proxy 和 Composition API)进一步提升了性能和灵活性。






