答案:通过Object.defineProperty实现数据劫持,结合模板编译与Watcher订阅者模式,构建极简MVVM框架,实现数据变化自动更新视图的核心机制。

要实现一个简单的MVVM(Model-View-ViewModel)框架,核心是数据绑定和响应式更新。我们可以通过JavaScript的Object.defineProperty或Proxy监听数据变化,并在视图中自动更新对应的内容。下面是一个极简版MVVM的实现思路与代码示例。
1. 核心原理:数据劫持 + 模板编译
MVVM的核心在于双向绑定:当数据变化时,视图自动更新;视图变化(如输入框输入)也能反过来影响数据。这需要以下三个关键部分:
Observer(监听器):监听数据变化,使用defineProperty或Proxy对数据进行劫持 Compiler(编译器):解析模板中的指令(如v-model, {{ }}),绑定数据并初始化视图 Watcher(订阅者):连接Observer和Compiler,当数据变化时触发视图更新
2. 使用 defineProperty 实现响应式数据
通过Object.defineProperty对对象的属性进行getter/setter重写,从而实现监听。
function observe(data) { if (!data || typeof data !== 'object') return; Object.keys(data).forEach(key => { let value = data[key]; observe(value); // 递归监听嵌套对象 Object.defineProperty(data, key, { enumerable: true, configurable: true, get() { return value; }, set(newVal) { if (value === newVal) return; value = newVal; observe(newVal); // 新值如果是对象也要监听 updateView(); // 触发视图更新 } }); });}
3. 编译模板并替换插值表达式
遍历DOM节点,查找{{ }}语法并替换成对应的数据值。
立即学习“Java免费学习笔记(深入)”;
function compile(el, vm) { const element = document.querySelector(el); _compile(element); function _compile(node) { if (node.nodeType === 3) { // 文本节点 const text = node.textContent; const reg = /{{(.+?)}}/g; // 匹配 {{ }} if (reg.test(text)) { const prop = RegExp.$1.trim(); node.textContent = text.replace(reg, vm[prop]); // 创建 watcher 监听数据变化 new Watcher(vm, prop, (newVal) => { node.textContent = text.replace(/{{.+?}}/g, newVal); }); } } if (node.childNodes && node.childNodes.length) { Array.from(node.childNodes).forEach(n => _compile(n)); } }}
4. 实现简易 Watcher 订阅器
Watcher用于在数据变化时执行对应的更新函数。
class Watcher { constructor(vm, prop, callback) { this.vm = vm; this.prop = prop; this.callback = callback; this.value = this.get(); // 触发 getter,完成依赖收集 } get() { Dep.target = this; // 暂存当前 watcher const value = this.vm[this.prop]; // 触发 getter,会通知它被访问了 Dep.target = null; return value; } update() { const newVal = this.vm[this.prop]; if (newVal !== this.value) { this.callback(newVal); } }}
可以配合一个简单的Dep类来管理依赖:
const Dep = { target: null, dependents: []};
5. 整合成一个 MVVM 类
class TinyMVVM { constructor(options) { this.$el = options.el; this.$data = options.data; // 数据代理:让 this.xxx 可以访问 this.$data.xxx Object.keys(this.$data).forEach(key => { this.proxyData(key); }); observe(this.$data); compile(this.$el, this); } proxyData(key) { Object.defineProperty(this, key, { get() { return this.$data[key]; }, set(newVal) { this.$data[key] = newVal; } }); }}
使用方式:
const vm = new TinyMVVM({ el: '#app', data: { message: 'Hello MVVM!' }});
HTML 示例:
{{ message }}
当vm.message = "Updated"时,页面上的文本会自动更新。
基本上就这些。虽然这个实现非常简化,没有处理复杂指令、事件绑定或数组变化,但它展示了MVVM的核心机制:数据劫持、依赖收集、模板编译和自动更新。理解这些原理有助于深入掌握Vue等现代框架的工作方式。
以上就是JavaScript实现一个简单的MVVM框架_js框架原理的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1536515.html
微信扫一扫
支付宝扫一扫