Ale.js

深入响应式原理

简介

Ale 使用 ES5 全新的 defineProperty 属性给对象添加 setter 和 getter。同时 Object.defineProperty 是 ES5 中一个无法 shim 的特性,并不是语法糖,这也就是为什么 Ale 不支持 IE8 以及更低版本浏览器。

限制

受现代 JavaScript 的限制 (而且 Object.observe 也已经被废弃),Ale 不能检测到对象属性的添加或删除。由于 Ale 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Ale 转换它,这样才能让它是响应的。例如:

1
2
3
4
5
6
7
data: {
a: 1
}

data.a = 2; /* 响应式 */

data.b = 2; /* 非响应式 */

所以当你设置数据时,必需 设置需要具有响应式效果数据的值,哪怕它只是一个空值:

1
2
3
4
data: {
a: 1,
b: '' /* 这里需要设置为空 */
}

具体

当你触发 setter(操作数据更新时),Ale 首先会更新这些数据,然后计算出更新后的全部属性结果,并循环更新。


其中,template属性比较特殊,当数据更新完成后,Ale 会调用 diff 算法的函数,并生成一个 伪DOM结构体,Ale的diff算法将会比较 伪DOM结构真实DOM结构 的区别,并且只更新有差异的 DOM 元素。


另外,diff 对比只会在同级 DOM 中进行,一旦发生层级改变,Ale 将不会继续对比,而是直接更新整个层。这样可以有效地增加 diff 的对比性能,减少对比的时间。


还有一点,Ale 的 diff 算法会对比元素的 内容 \ 属性 【1.1.0版本前只会对比 内容 \ id \ class \ name 是否相同,也就是说,当你动态更新其他类型的内容,diff 算法是不会对比出差异的,而元素也就不会更新。这时你可以在元素更新时手动关闭 diff 算法,并在元素更新完成时开启即可!


找到了一些错误?在Github上编辑!