深入响应式原理
简介
Ale 使用 ES5 全新的 defineProperty
属性给对象添加 setter 和 getter。同时 Object.defineProperty 是 ES5 中一个无法 shim 的特性,并不是语法糖,这也就是为什么 Ale 不支持 IE8 以及更低版本浏览器。
限制
受现代 JavaScript 的限制 (而且 Object.observe
也已经被废弃),Ale 不能检测到对象属性的添加或删除。由于 Ale 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Ale 转换它,这样才能让它是响应的。例如:
- data: {
a: 1
}
data.a = 2; /* 响应式 */
data.b = 2; /* 非响应式 */
所以当你设置数据时,必需 设置需要具有响应式效果数据的值,哪怕它只是一个空值:
- data: {
a: 1,
b: '' /* 这里需要设置为空 */
}
具体
当你触发 setter(操作数据更新时),Ale 首先会更新这些数据,然后计算出更新后的全部属性结果,并循环更新。
其中,template
属性比较特殊,当数据更新完成后,Ale 会调用 diff
算法的函数,并生成一个 伪DOM结构体
,Ale的diff算法将会比较 伪DOM结构
和 真实DOM结构
的区别,并且只更新有差异的 DOM 元素。
另外,diff 对比只会在同级 DOM 中进行,一旦发生层级改变,Ale 将不会继续对比,而是直接更新整个层。这样可以有效地增加 diff 的对比性能,减少对比的时间。
还有一点,Ale 的 diff
算法只会对比元素的 内容
\ id
\ class
\ name
属性是否相同,也就是说,当你动态更新例如 onclick
之类的属性,diff
算法是不会对比出差异的,而元素也就不会更新。这时你可以在元素更新时手动关闭 diff
算法,并在元素更新完成时开启即可!