做者:Daybrush翻译:疯狂的技术宅javascript
原文:https://medium.com/naver-fe-p...前端
未经容许严禁转载vue
跨框架组件(Cross Framework Component (CFC))是一种支持各类框架的基于单个通用模块有效结构。java
跨框架组件用到了跨平台的方法。 跨平台是一种容许你在各类平台(操做系统,设备)上使用单一源代码的结构,能够经过 Xamarin、Flutter、NativeScript 和 React Native 等工具在 iOS、Android 和 Windows 中使用。react
跨框架组件在 React、Angular、Vue 等中也可做为单个原生组件使用。git
在框架中使用传统的原生组件有两种方法:程序员
第一个方法(现有原生组件的简单包装)是用户最经常使用的方法。由于它很是简单易行。github
可是,当DOM中没有变化(add
/remove
/move
)时,这是一个合适的方法。由于框架会将你的数据同步到DOM。可是,若是原生组件操纵 DOM,则会阻止框架与 DOM 同步。面试
这时框架中的数据和 DOM 之间的关系会变得混乱。实际上,从组件中删除 DOM 可能会致使如下错误:segmentfault
React中的DOM错误
由于框架正在寻找已被删除的 DOM。因此若是你想使用现有原生组件的简单包装,就不要操做 DOM。
第二个方法(建立一个新的框架组件)是为特定框架建立一个的新的组件。可是把现有的原生组件再次专用于框架又有什么不对呢?
固然因为建立了特定于框架的组件,所以框架的所需功能能够正常工做。可是若是把现有的原生组件从新建立为框架组件,则维护会变得很是困难,由于每一个框架中都有多份代码。因此从没有原生组件的框架组件从新开始是一个的好方法。
egjs 已经开始考虑使用跨框架组件来解决上述两种方法中存在的问题。
如下是跨框架组件如何解决问题以及如何将其应用于原生组件的方法。
正如我以前所说的,框架须要与 DOM 同步,但原生组件会干扰同步。
所以跨框架组建不会操纵原生组件中的 DOM。并且在从框架同步到 DOM 以后,会再次将同步的 DOM 同步到数据。
这样,你能够经过清晰的同步顺序来获取所需的数据,而不会形成相互中断。那么咱们该怎样从 DOM 同步到数据呢?
它还作用于组件上,用来将框架与 DOM 同步。
以相同的方式同步
假设存在框架数据 1, 2, 3, 4, 5, 6
,DOM 中的数据顺序为 1, 2, 3, 4, 5, 6
,组件数据的顺序为 1,2,3,4,5,6
。
若是你要把框架数据 6
移动到框架数据 3
前面。
而后,经过同步 DOM 中的框架数据,DOM 中的 元素 6 移动到元素 3 前面。
最后,同步最后的 DOM,原生组件中的数据 6
也移动到数据 3
的前面。
你能够用与框架相同的方式同步它。可是我不知道如何与 React、Angular 或 Vue 同步,而且 React、Angular 和 Vue 使用的全部方法都不同。所以,你能够建立相似的方法并使结果相同,而不是以相同的方式建立它。
ListDiffer 是一个比较库,用于检测列表(或数组)中的更改并跟踪更改的进度。
在React、Angular 和 Vue 中确定有相似的比较函数来跟踪变动过程。
可是,egjs 建立了 ListDiffer,这是一个能够在 React、Angular 和 Vue 中使用的库,并经过这个库进行同步。能够在如下文章中找到更多信息:
https://medium.com/p/27793f0c...
这可以容许你从 DOM 同步到 组件,而没必要知道如何在框架中使用它。
在跨平台的状况下,为了在各类操做系统上进行操做,这须要一个 supporter 将框架 API 与操做系统 API 进行链接。
跨框架组件也是如此。在各类框架下运行须要一个 supporter,能够将 ListDiffer API与框架 API链接起来。
使用 list-different API,能够轻松建立React、Angular和Vue组件。
应用跨框架组件有两种方法:使用数据跟踪(效率处理方法)和不使用数据跟踪(一步处理方法)。
使用数据跟踪是一种尽量减小处理次数的好方法。
原生组件的内部 DOM 操做必须是可选的,以便使现有的原生组件成为跨框架组件。此方法称为渲染外部化选项。当你使用原生组件时将会使用 DOM 方法,例如 appendChild 和 removeChild,但在框架中你能够经过激活渲染外化选项来阻止 DOM 方法,例如 appendChild 和 removeChild。
你能够按如下顺序编写代码来使用它: removed
> ordered
> added
:
const { removed, added, ordered, pureChanged, list } = result; removed.forEach(index => { inst.remove(index); }); ordered.forEach(([from, to], i) => { inst.remove(from); inst.insert(to, list[pureChanged[i][1]]); }); added.forEach(index => { inst.insert(index, list[index]); });
removed
是你想要的索引数组。经过 remove 方法从索引中删除数据。ordered
是要移动的数组起始索引和结束索引。 remove 方法容许你经过从该索引中删除数据,并将其添加到将经过 insert 方法访问的索引来移动数字。added
是要添加的索引数组。经过 insert 方法将数据添加到索引中。若是方法匹配,则实际上只须要经过复制/粘贴这段代码就好了。
不使用数据跟踪是批量处理的好方法**。
要实现“不使用数据跟踪方法”须要如下项目:
使用数据跟踪的方法中有一个 insert 方法,一个 remove 方法,可是不使用数据跟踪的方法须要一个用来进行批处理的同步方法。
若是你不想使用数据跟踪,能够根据状况省略它,并记住处理顺序 maintained
> added
。
以不使用数据跟踪的方式建立 Flicking 3,如下代码是 Flicking 的一部分。
function sync(result) { const { maintained, removed, added, list } = result; const prevItems = this.items; const newItems = []; maintained.forEach(([beforeIndex, afterIndex]) => { newItems[afterIndex] = prevItems[beforeIndex]; }); added.forEach(i => { newItems[i] = new Item(list[i]); }); this.items = newItems; this.recaculateItems(); }
使用 maintain
,你只能导入先前数据的维护部分,并经过 added
添加新数据。
Flicking 的最后一个方法 caculateSize()
批量获取 DOM 的大小。若是使用“数据跟踪”,则每次都会进行布局操做,而且可能会出现性能问题。
Flick
由三个关键框架支持:react-flicking
,ngx-flicking
和 vue-flicking
,而且可使用 Flicking 的大部分功能。
本文介绍了跨框架组件的特性、原理和用法。
InfiniteGrid
也将要使用跨框架组件的方法。它提供了有限的 React 支持,但你很快就会看到在 React、Angular 和 Vue 组件中提供的大量功能。
许多人在使用 egjs,并且正在用到许多框架中,如React、Angular 和 Vue。之前它须要花费两倍的时间来进行处理,由于它是用两组代码进行管理的。未来,Flicking
和 InfiniteGrid
将被集成到跨框架组件结构中,为你的查询提供可靠的响应,让你更快地知足各类功能的需求。