原文连接-https://github.com/AlloyTeam/omi/tree/master/tutorialhtml
Omi框架在架构设计的时候就决定把update的控制权交给了开发者,视灵活性比生命还重要。否则的话,若是遇到React Fiber要解决的这类问题的话,就须要推翻原有架构从新搞了。node
先引用下咱们团队小鲜肉Stark伟-复旦大四 / 腾讯@AlloyTeam在知乎上的回答react
React 的核心思想是每次对于界面 state 的改动,都会从新渲染整个 virtual dom,而后新老的两个 virtual dom 树进行 diff,对比出变化的地方,而后经过 renderer 渲染到实际的UI界面(这里多是浏览器的DOM,也多是native组件)。这样实质上就是把界面变成一个纯粹的状态机,React 的做用就是把这个状态机之间的状态转换高效率地运行出来。可是存在如下问题:git
或者看颜什么都不记得适的回答:程序员
状态转移时,是在一次 tick 中递归遍历组件树,找出须要更新的节点 rerender。可是这样形成了一些问题:github
Omi有上面的问题吗? 没有。web
Omi的卖点之一即是:更自由的更新,每一个组件都有update方法,自由选择你认为最佳的时机进行更新。这样设计的一大好处是更加灵活,若是想要自动更新集成个mobx或者obajs即可,进可功退可守护。
数据和视图虽然是关系密切,可是解耦的设计仍是很是必要,这样能够应付更多的场景。好处:浏览器
component update说完了吗?没有... Omi不只仅有component update!还有更增强大的 updateSelf。架构
先说下二者的区别:框架
以下图所示:
标红的表明会进行更新的节点。
class TestComponent extends Omi.Component { render () { return `<div> <h3>{{title}}</h3> <List name="list" data="listData" /> </div>`; } }
组件结构上面代码所示:
好比咱们仅仅修改了this.data.title,就能够调用this.updateSelf方法,虽然通常状况下无脑update也能达到一样的结果,虽然morphdom的DOM diff已经足够轻量快速,可是必定没有updateSelf方法快速。上面的例子updateSelf优点可能不明显,若是这样呢:
class TestComponent extends Omi.Component { render () { return `<div> <h3>{{title}}</h3> <List name="list" data="listData" /> <List name="list" data="listData" /> <Content name="list" data="listData" /> <Slider name="list" data="listData" /> </div>`; } }
再或者Content、Slider里面再嵌套了子组件,子组件又嵌套了子组件,若是仅仅只是须要修改title的话,updateSelf优点就尽显无疑。
这里主要说一说updateSelf的实现细节。主要包含两点:
进行updateSelf的时候,就算子组件的data发生了变化,也不去改变子组件。由于updateSelf就意思就是更新自身。
因此子组件的HTML不须要使用模板和data生成,只须要component.node.outerHTML就能够了。outerHTML在古老的firefox是不支持的,能够经过建立节点插入而后读innerHTML进行polyfill。
组件自己的HTML是须要使用模板和data生成,子组件就使用刚刚的outerHTML替换即可。可是问题来了,子组件的DOM diff实际上是没有必要的,虽然morphdom的DOM diff已经足够轻量快速。可是子组件他们原本就是如出一辙,没有必要的开销。因此须要关闭DOM diff~~。而后morphdom没有ignore相关的配置....
API:
morphdom(node, newNodeHTML, { ignoreAttr: ['attr1','attr2'] } )
好比上面表明只要标记了attr1或者attr2的就是忽略,固然为了规避错误,这里须要严格的匹配才会ignore DOM diff。怎么算严格的匹配?就是:
Omi Store体系之前经过addView进行视图收集,store进行update的时候会调用组件的update。
与此同时,Omi Store体系也新增了addSelfView的API。
固然,store内部会对视图进行合并,好比addView里面加进去的全部视图有父子关系的,会把子组件去掉。爷孙关系的会把孙组件去掉。addSelfView收集的组件在addView里已经收集的也去进行合并去重,等等一系列合并优化。