vue实现mvvm思路
Vue 实现 MVVM 的思路
Vue 的 MVVM(Model-View-ViewModel)实现主要通过数据绑定和响应式系统完成。以下是核心实现思路:
数据劫持(响应式系统)
通过 Object.defineProperty 或 Proxy 拦截数据的读取和修改。当数据变化时,通知依赖的视图更新。
// 简化版数据劫持
function defineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
get() {
console.log('get', key);
return val;
},
set(newVal) {
if (newVal !== val) {
console.log('set', key);
val = newVal;
// 触发更新
}
}
});
}
依赖收集
每个响应式数据维护一个依赖列表(Dep),在 getter 中收集依赖(Watcher),在 setter 中通知依赖更新。
class Dep {
constructor() {
this.subs = [];
}
addSub(sub) {
this.subs.push(sub);
}
notify() {
this.subs.forEach(sub => sub.update());
}
}
class Watcher {
update() {
// 更新视图
}
}
模板编译
将模板解析为 AST(抽象语法树),遍历 AST 生成渲染函数。过程中识别指令(如 v-model)和插值表达式({{}}),并为其创建对应的 Watcher。
// 简化的模板编译
function compile(template) {
// 解析模板为 AST
const ast = parse(template);
// 生成渲染函数
const code = generate(ast);
return new Function(code);
}
虚拟 DOM 与 Diff 算法
通过虚拟 DOM 减少直接操作真实 DOM 的开销。当数据变化时,生成新的虚拟 DOM,通过 Diff 算法对比新旧虚拟 DOM,高效更新真实 DOM。
// 简化的虚拟 DOM 结构
{
tag: 'div',
attrs: { id: 'app' },
children: [
{ tag: 'span', children: 'Hello' }
]
}
双向绑定实现
v-model 是语法糖,通过绑定 value 属性和 input 事件实现双向绑定。
// 简化的 v-model 实现
function bindModel(el, vm, exp) {
el.value = vm[exp];
el.addEventListener('input', e => {
vm[exp] = e.target.value;
});
}
生命周期管理
组件在不同阶段(创建、挂载、更新、销毁)触发对应的生命周期钩子,便于开发者介入控制流程。
Vue 的 MVVM 实现通过以上机制,实现了数据驱动视图的自动化更新,开发者只需关注数据状态,无需手动操作 DOM。







