vue 如何实现mvvm的
Vue 的 MVVM 实现原理
Vue 通过数据绑定、响应式系统和虚拟 DOM 等技术实现 MVVM(Model-View-ViewModel)模式。以下是核心实现机制:
数据劫持与响应式系统
Vue 使用 Object.defineProperty(Vue 2)或 Proxy(Vue 3)劫持数据对象的属性访问和修改。当数据变化时,触发依赖更新。
Vue 2 示例:
Object.defineProperty(obj, key, {
get() { return value; },
set(newVal) {
if (newVal !== value) {
value = newVal;
dep.notify(); // 通知依赖更新
}
}
});
Vue 3 的 Proxy:
const proxy = new Proxy(data, {
get(target, key) { track(target, key); return target[key]; },
set(target, key, value) {
target[key] = value;
trigger(target, key); // 触发更新
}
});
依赖收集与发布订阅
每个响应式属性关联一个 Dep(依赖收集器),Watcher(观察者)在渲染过程中订阅依赖。数据变化时,Dep 通知所有 Watcher 更新视图。
依赖收集流程:
- 组件渲染时触发
getter,将当前 Watcher 添加到Dep中。 - 数据修改时触发
setter,Dep通知所有 Watcher 执行更新。
虚拟 DOM 与 Diff 算法
Vue 将模板编译为虚拟 DOM(VNode),通过 Diff 算法比对变化,最小化真实 DOM 操作。
Patch 过程:
function patch(oldVnode, newVnode) {
if (sameVnode(oldVnode, newVnode)) {
patchVnode(oldVnode, newVnode); // 精细化比对子节点
} else {
replaceNode(oldVnode, newVnode); // 直接替换
}
}
模板编译
Vue 将模板编译为渲染函数,生成虚拟 DOM:
- 解析:将模板转换为 AST(抽象语法树)。
- 优化:标记静态节点,跳过 Diff。
- 生成代码:将 AST 转换为可执行的渲染函数。
示例输出:
with(this) {
return _c('div', { attrs: { id: 'app' } }, [_v("Hello " + _s(name))]);
}
双向数据绑定
通过 v-model 指令实现表单元素与数据的双向绑定,本质是语法糖:
<input v-model="message">
<!-- 等价于 -->
<input :value="message" @input="message = $event.target.value">
总结
Vue 的 MVVM 实现核心:
- Model:普通 JavaScript 对象,通过响应式系统监听变化。
- View:模板或渲染函数生成的虚拟 DOM。
- ViewModel:Vue 实例,负责数据与视图的同步,通过响应式机制、虚拟 DOM 和模板编译实现解耦。







