专栏名称: 前端JavaScript
分享 | 学习 | 交流 | 原创 分享是学习的开始;学习不必要从头开始,是从现在开始;交流能沟通你我,提高你的学识;期待你的加入!!! web前端技术交流,JavaScript,HTML5,CSS3……
目录
相关文章推荐
51好读  ›  专栏  ›  前端JavaScript

[S3-E398]利用 JavaScript 数据绑定实现一个简单的 MVVM 库

前端JavaScript  · 公众号  · Javascript  · 2017-08-04 07:34

正文

请到「今天看啥」查看全文



上述流程如图所示:



下文就介绍下这五个模块实现的基本原理(代码只贴重点部分,完整的实现请到我的 Github 翻阅)


1. 编译模块 Compiler

Compiler 的职责主要是对元素的每个节点进行指令的扫描和提取。因为编译和解析的过程会多次遍历整个节点树,所以为了提高编译效率在 MVVM 构造函数内部先将 element 转成一个文档碎片形式的副本 fragment 编译对象是这个文档碎片而不应该是目标元素,待全部节点编译完成后再将文档碎片添加回到原来的真实节点中。


vm.complieElement 实现了对元素所有节点的扫描和指令提取:


vm.complieElement = function(fragment, root) {

var node, childNodes = fragment.childNodes;

// 扫描子节点

for (var i = 0; i < childNodes.length; i++) {

node = childNodes[i];

if (this.hasDirective(node)) {

this.$unCompileNodes.push(node);

}

// 递归扫描子节点的子节点

if (node.childNodes.length) {

this.complieElement(node, false);

}

}

// 扫描完成,编译所有含有指令的节点

if (root) {

this.compileAllNodes();

}

}

vm.compileAllNodes 方法将会对 this.$unCompileNodes 中的每个节点进行编译(将指令信息交给 Parser ),编译完一个节点后就从缓存队列中移除它,同时检查 this.$unCompileNodes.length 当 length === 0 时说明全部编译完成,可以将文档碎片追加到真实节点上了。


2. 指令解析模块 Parser

当编译器 Compiler 把每个节点的指令提取出来后就可以给到解析器解析了。每一个指令都有不同的解析方法,所有指令的解析方法只要做好两件事:一是将数据值更新到视图上(初始状态),二是将刷新函数订阅到 Model 的变化监测中。这里以解析 v-text 为例描述一个指令的大致解析方法:


parser.parseVText = function(node, model) {

// 取得 Model 中定义的初始值

var text = this.$model[model];

// 更新节点的文本

node.textContent = text;

// 对应的刷新函数:

// updater.updateNodeTextContent(node, text);

// 在 watcher 中订阅 model 的变化

watcher.watch(model, function(last, old) {

node.textContent = last;

// updater.updateNodeTextContent(node, text);

});

}


3. 数据订阅模块 Watcher

上个例子,Watcher 提供了一个 watch 方法来对数据变化进行订阅,一个参数是模型字段 model 另一个是回调函数,回调函数是要通过 Observer 来触发的,参数传入新值 last 和 旧值 old , Watcher 拿到新值后就可以找到 model 对应的回调(刷新函数)进行更新视图了。model 和 刷新函数是一对多的关系,即一个 model 可以有任意多个处理它的回调函数(刷新函数),比如:v-text="title" 和 v-html="title" 两个指令共用一个数据模型字段。







请到「今天看啥」查看全文