深入响应式原理

简介

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

限制

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

  1. data: {
    a: 1
    }

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

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

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

  1. 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 算法,并在元素更新完成时开启即可!

原文: https://cn.alejs.org/2018/12/01/deepInRespond