做者: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
將被集成到跨框架組件結構中,爲你的查詢提供可靠的響應,讓你更快地知足各類功能的需求。