JavaScript数据绑定实现一个简单的数据绑定实现一个简单的 MVVM 库库
MVVM 是 Web 前端一种非常流行的开发模式,利用 MVVM 可以使我们的代码更专注于处理业务逻辑而不是去
关心DOM 操作。接下来通过本文给大家介绍JavaScript使用数据绑定实现一个简单的 MVVM 库,感兴趣的朋友
一起学习吧
推荐阅读:推荐阅读:
实现非常简单的js双向数据绑定
MVVM 是 Web 前端一种非常流行的开发模式,利用 MVVM 可以使我们的代码更专注于处理业务逻辑而不是去关心 DOM 操
作。目前著名的 MVVM 框架有 vue, avalon , react 等,这些框架各有千秋,但是实现的思想大致上是相同的:数据绑定 + 视
图刷新。出于好奇和一颗愿意折腾的心,我自己也沿着这个方向写了一个最简单的 MVVM 库 ( mvvm.js ),总共 2000 多行代
码,指令的命名和用法与 vue 相似,在这里分享一下实现的原理以及我的代码组织思路。
思路整理思路整理
MVVM 在概念上是真正将视图与数据逻辑分离的模式,ViewModel 是整个模式的重点。要实现 ViewModel 就需要将数据模型
(Model)和视图(View)关联起来,整个实现思路可以简单的总结成 5 点:
实现一个 Compiler 对元素的每个节点进行指令的扫描和提取;
实现一个 Parser 去解析元素上的指令,能够把指令的意图通过某个刷新函数更新到 dom 上(中间可能需要一个专门负责视图
刷新的模块)比如解析节点 <p v-show="isShow"></p> 时先取得 Model 中 isShow 的值,再根据 isShow 更改
node.style.display 从而控制元素的显示和隐藏;
实现一个 Watcher 能将 Parser 中每条指令的刷新函数和对应 Model 的字段联系起来;
实现一个 Observer 使得能够对对象的所有字段进行值的变化监测,一旦发生变化时可以拿到最新的值并触发通知回调;
利用 Observer 在 Watcher 中建立一个对 Model 的监听 ,当 Model 中的一个值发生变化时,监听被触发,Watcher 拿到新值
后调用在步骤 2 中关联的那个刷新函数,就可以实现数据变化的同时刷新视图的目的。
效果示例效果示例
首先粗看下最终的使用示例,与其他 MVVM 框架的实例化大同小异:
<div id="mobile-list">
<h1 v-text="title"></h1>
<ul>
<li v-for="item in brands">
<b v-text="item.name">
<span v-show="showRank">Rank: {{item.rank}}</span>
</li>
</ul>
</div>
var element = document.querySelector('#mobile-list');
var vm = new MVVM(element, {
'title' : 'Mobile List',
'showRank': true,
'brands' : [
{'name': 'Apple', 'rank': 1},
{'name': 'Galaxy', 'rank': 2},
{'name': 'OPPO', 'rank': 3}
]
});
vm.set('title', 'Top 3 Mobile Rank List'); // => <h1>Top 3 Mobile Rank List</h1>
模块划分模块划分
我把 MVVM 分成了五个模块去实现: 编译模块 Compiler 、解析模块 Parser 、视图刷新模块 Updater 、数据订阅模块
Watcher 和 数据监听模块 Observer 。流程可以简述为:Compiler 编译好指令后将指令信息交给解析器 Parser 解析,Parser
更新初始值并向 Watcher 订阅数据的变化,Observer 监测到数据的变化然后反馈给 Watcher ,Watcher 再将变化结果通知
Updater 找到对应的刷新函数进行视图的刷新。
上述流程如图所示:
下文就介绍下这五个模块实现的基本原理(代码只贴重点部分,完整的实现请到我的下文就介绍下这五个模块实现的基本原理(代码只贴重点部分,完整的实现请到我的 Github 翻阅)翻阅)
1. 编译模块编译模块 Compiler
Compiler 的职责主要是对元素的每个节点进行指令的扫描和提取。因为编译和解析的过程会多次遍历整个节点树,所以为了