js实现mvvm
MVVM 模式简介
MVVM(Model-View-ViewModel)是一种前端架构模式,核心思想是将视图(View)与业务逻辑(ViewModel)解耦,通过数据绑定实现双向同步。Model 管理数据,View 负责渲染,ViewModel 作为桥梁处理逻辑和状态。

实现 MVVM 的关键技术
-
数据劫持(响应式数据)
通过Object.defineProperty或Proxy监听数据变化,触发更新。
// 使用 Proxy 实现响应式 function reactive(obj) { return new Proxy(obj, { get(target, key) { return target[key]; }, set(target, key, value) { target[key] = value; updateView(); // 触发视图更新 return true; } }); } -
模板编译
解析 HTML 模板中的指令(如v-model、{{}}),替换为动态数据并绑定事件。function compile(template, data) { return template.replace(/\{\{(.*?)\}\}/g, (_, key) => { return data[key.trim()]; }); } -
依赖收集与发布订阅
为每个数据属性维护一个依赖列表(Dep),当数据变化时通知所有依赖(Watcher)更新。class Dep { constructor() { this.subscribers = []; } depend() { if (Watcher.target) this.subscribers.push(Watcher.target); } notify() { this.subscribers.forEach(watcher => watcher.update()); } }
完整实现示例
class MVVM {
constructor(options) {
this.$el = document.querySelector(options.el);
this.$data = options.data;
this.observe(this.$data);
this.compile(this.$el);
}
observe(data) {
Object.keys(data).forEach(key => {
let value = data[key];
const dep = new Dep();
Object.defineProperty(data, key, {
get() {
if (Watcher.target) dep.depend();
return value;
},
set(newVal) {
value = newVal;
dep.notify();
}
});
});
}
compile(node) {
Array.from(node.childNodes).forEach(child => {
if (child.nodeType === 3) { // 文本节点
const text = child.textContent;
const reg = /\{\{(.*?)\}\}/g;
if (reg.test(text)) {
const key = RegExp.$1.trim();
new Watcher(this.$data, key, () => {
child.textContent = text.replace(reg, this.$data[key]);
});
}
} else if (child.nodeType === 1) { // 元素节点
Array.from(child.attributes).forEach(attr => {
if (attr.name === 'v-model') {
const key = attr.value;
child.value = this.$data[key];
child.addEventListener('input', e => {
this.$data[key] = e.target.value;
});
new Watcher(this.$data, key, () => {
child.value = this.$data[key];
});
}
});
this.compile(child);
}
});
}
}
class Watcher {
constructor(data, key, cb) {
Watcher.target = this;
this.cb = cb;
data[key]; // 触发 getter,收集依赖
Watcher.target = null;
}
update() {
this.cb();
}
}
使用示例
<div id="app">
<input v-model="message">
<p>{{ message }}</p>
</div>
<script>
const vm = new MVVM({
el: '#app',
data: { message: 'Hello MVVM!' }
});
</script>
优化方向
- 虚拟 DOM:减少直接 DOM 操作,通过 diff 算法批量更新。
- 指令扩展:支持
v-for、v-if等复杂指令。 - 性能优化:避免不必要的依赖触发,如计算属性缓存。
通过以上实现,可以构建一个基础的 MVVM 框架,类似 Vue 的响应式原理。






