如果你想了解 MVVM 双向数据绑定,那你之前最好有 Angular.js/React.js/Vue.js 等工具库的使用经验,便于理解。
一、实现思路
要实现一个 mvvm 双向数据绑定,我们需要实现以下几点:
- 实现一个数据监听器
Observer,能够对数据对象的所有属性进行监听,当数据变更时能通过发布者通知所有订阅者。 - 实现一个指令和模板的解析器
Compile,能对各个元素节点进行扫描解析,将对应的数据模板替换成对应的数据,并且更新到视图上。 - 利用订阅者
Watcher连接Observer和Compile,使得监听数据变更时,视图能变化。视图绑定数据变化时,数据对象也能进行相应的变化。 - 提供一个 MVVM 函数,支持以上三个能力。
流程示意图:
二、具体实现
1. 实现数据监听 Observer
利用 Object.defineProperty 拦截 data 数据变化。
监听者 observer.js
1 | class Observer { |
发布者 dependence.js
1 | class Dependence { |
每当 data 数据发生变更时,setter 拦截器都会通知发布者,从而通知所有相关的订阅者。
2. 实现DOM编译 Compile
Compile 主要负责模板的解析和初始化页面视图。
由于在解析过程涉及到多次dom元素的操作,为了避免引起页面的多次回流,我们可以利用 fragment 文档片段进行处理,处理结束后再将 fragment 插入原来的节点中。
编译者 compiler.js
1 | class Compile { |
3. 实现依赖收集 Watcher
依赖收集:
新增订阅者时,将当前订阅者赋值给一个全局变量,之后触发相关联的数据的
getter,getter就能将全局变量中包含的订阅者添加到相关的订阅者列表中。
连接
Observer和Compile:当
Compile解析指令或数据模板时,发现有效指令或数据模板时,可新增一个订阅者相应的变化,并在回调中做出对应的处理。
订阅者 watcher.js
1 | class Watcher { |
observer.js 新增
1 | class Observer { |
4. 提供入口构造函数 MVVM
mvvm.js
1 | class MVVM { |
三、补充
相关源码地址:请访问
