前言
avalon2是一款基于虚拟DOM与属性劫持的 迷你、 易用、 高性能 的 前端MVVM框架, 拥有超优秀的兼容性, 支持移动开发, 后端渲染, WEB Component式组件开发, 无需编译, 开箱即用。
网上对Avalon的评价褒贬不一,但是我个人还是比较喜欢这个框架的,为什么呢?业务需要,我们需要兼容古老的IE,所以不能盲目的追求所谓的新技术,而MVVM框架中能够做到兼容旧版本IE的,Avalon无疑是非常出色的。至于Avalon与其他的一些MVVM框架,孰优孰劣,这里不做评价。
教程:http://avalonjs.coding.me
下载地址:https://github.com/RubyLouvre/avalon/releases
浏览器支持
性能比较
Avalon2官方教程中提供的主流MVVM框架性能比较
如何使用Avalon2,我们直接下载下来的压缩包中可以发现有三个版本的Avalon的js,分别为:arthur.js
、avalon.js
和avalon.modern.js
。我们可以根据实际情况进行选择。
arthur.js
:一个迷你版avalon,支持IE9+
avalon.js
:支持IE6+及古老的W3C浏览器(判定标准是浏览器是否支持VBScript, defineSetter, defineGetter)
avalon.modern.js
:支持IE10+及较新的W3C浏览器(判定标准是浏览器是否支持Object.defineProperty, addEventListener)
为了给用户提供最佳的性能体验,通常情况我会在页面中通过hack方式引用Avalon的js文件。
<script type="text/javascript" src='lib/avalon/avalon.modern.js'></script>
<!--[if lt IE 9]>
<script type="text/javascript" src='lib/avalon/avalon.js'></script>
<![endif]-->
示例
第一个Avalon例子:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>HelloAvalon</title>
<script type="text/javascript" src="js/avalon.js"></script>
<script>
var vm = avalon.define({
$id: "test",
welcom: "Hello Avalon!"
});
</script>
</head>
<body ms-controller="test">
<div>{{welcom}}</div>
</body>
</html>
运行效果如图:
虚拟DOM
- 第1阶段:avian会在
DOMReady
对.ms-controller
节点进行outerHTML
操作。 - 第2阶段:将这个字符串进行parser,转换为虚拟DOM 这个阶段对
input/textarea
元素补上type
属性,ms-*
自定义元素补上ms-widget
属性, 对table
元素补上tbody
, 在ms-for
指令的元素两旁加上 , 占位符, 并将它们的之间的元素放到一个数组中(表明它们是循环区域) 并去掉所有只有空白的文本节点。 - 第3个阶段:优化,对拥有ms-属性的虚拟DOM添加dynamic属性 表明它以后要保持其对应的真实节点,并对没有ms-属性的元素添加skipAttrs属性,表明以后不需要遍历其属性。 如果它的子孙没有ms-*或插值表达式或ms-自定义元素,那么还加上skipContent,表明以后不要遍历其孩子。这三个属性,dynamic用于节点对齐算法,skipAttrs与skipContent用于diff算法
- 第4个阶段:应用节点对齐算法, 将真实DOM中无用的空白节点移除,并插入占位符, 并将需要刷新的元素保持在以应的拥有dynamic属性的虚拟DOM中。
- 第5个阶段:放进render方法中,render方法里面再调parseView,parseView会调每个指令的parse方法 将虚拟DOM树转换为一个$render方法。
- 第6个阶段:执行$render方法,生成新的虚拟DOM,与最早的那个虚拟DOM树diff,一边diff一边更新真实DOM。以后VM的属性发生变动,就直接执行第6个阶段。
VM
avalon的所有操作都是围绕vm
进行。即view model
,视图模型。只要我将一个JS对象添加一个$id
属性, 再放到avalon.define
方法里面,就能得到一个vm
。
var vm = avalon.define({
$id: "test",
welcom: "Hello Avalon!"
});
vm
是一种利用Proxy
或Object.defineProperties
或VBScript
创建的特殊对象。
里面以$
带头的属性或放到$skipArray
,都转换为访问器属性,也就是其他语言的setter
, getter
。因此如果这个属性最初没有定义,那么它就不会转换为访问器属性,修改该属性,就不会刷新视图。
avalon定义了的vm,都可以在avalon.vmodels
中查看到。
构建
VM
时只允许存在普通对象(不能是某个函数的实例)、函数、数组、数字、字符串、布尔,(undefined与null不能出现在定义VM时,只能用它们来赋值)。