Hello很久不見。跳槽以後一直沒什麼時間總結記錄這段時間的見聞或實踐,好不容易擠出點時間,今天想記錄一下最近的一個組件設計&開發歷程,該組件的開發環境是小程序,可是我認爲這個思惟是通用的~前端
本文可能涉及內容--小程序
咱們大概須要完成這樣一個表單組件↓↓數組
由圖大體能夠判斷,咱們應該將此組件拆成兩塊,一個是tab選項區,一個是下方的附加選項區。數據結構
爲何須要分拆?優化
最主要的緣由是項目自身緣由,以前就有tab的組件,咱們能夠直接引用。設計
固然,就算咱們自身項目沒有這個組件,我也是建議拆分開來,由於在表單的開發中,這種tab選擇的形式能夠說太常見了,拆分開來確定是有益的,而且它的功能十分單一,很適合做爲一個獨立組件。3d
如何用數據結構描述組件?code
靜態結構大概明瞭,那麼咱們應該怎麼用數據來描述這個組件呢?接下來就來考慮一下組件的數據結構,開始以前先明確幾個前提--cdn
「tab數目不定、tab與附加項內容有聯動、附加項數目不定」blog
上圖是我在初版中構思的數據結構,制定該規則的緣由以下--
因爲tab數目不定,因此配置成數組由前端進行列表渲染最爲合適(附加項的設定也同理)。
由於tab與附加項內容有聯動,因此我將附加項直接與tab內聯,切換tab的時候直接切換相應的附加項數據便可。
因爲存在多個tab和多個附加項,因此一定會有組合排列的問題。在初版方案中,我採用的是map的處理方式,將選中的value值拼接到一塊兒,而後在valueMap中獲取最終的value值。(不一樣業務不一樣方式,若是不須要處理組合問題,可直接輸出所選的全部value值)
接下來邏輯就很順暢啦,咱們只須要獲取用戶最終選擇的value拼接值就能夠在valueMap中獲得目標數據。
可是這個方案是有瑕疵的,我忽略了配置複雜度,這樣在前端代碼中能夠很輕鬆的處理邏輯。可是會爲後續的配置帶來無窮後患,隨着方案數量的增長,組合的狀況會飛速增加。爲了不這個坑,我須要對valueMap作些優化。
valueMap的優化方案
如圖中代碼所示,擯棄原來鍵值一一對應的方式,採用根據tab項帶出value可選範圍的模式。
而後經過對選中選項的處理得出value可選範圍數組的下標。這樣在配置起來會比上一種方案好一點,相對前端的邏輯會稍微複雜一點,但前端的代碼只須要咱們寫一次,而配置則多是無數次。
新方案的前端邏輯大概是這樣,等等...怎麼看起來這麼彆扭?這段邏輯居然徹底和業務攪在一塊兒了,萬一新增附加項目豈不是爆炸了?萬一附加方案間也出現了組合狀況不也爆炸了:(
那豈不是表明這種方案更不靠譜?咱們是否是能夠試試將其與業務解耦?
JavaScript位運算簡介
位運算就是直接對整數在內存中的二進制位進行操做,與是否處於JavaScript環境並無什麼關聯,但咱們能夠藉助一下這種位運算的思惟。有關JavaScript位運算的相關文檔,在本文中咱們主要會使用按位移動的操做符來達到咱們的目的。
如何將兩者結合一塊兒?
直接上代碼,咱們看圖說話--
在新的邏輯中,咱們已經看不到對addon項value的依賴,取而代之是二進制形式的位置下標。假設咱們有這樣一個數組:
let A = [A-value-0, A-value-1, A-value-2, A-value-3]
分別對這種四種選擇狀況的取值--
選擇狀況 | 值 | 數組下標 | 二進制下標 |
---|---|---|---|
不選 | A-value-0 | A[0] | 00 |
選擇第一個 | A-value-1 | A[1] | 01 |
選擇第二個 | A-value-2 | A[2] | 10 |
全選 | A-value-3 | A[3] | 11 |
這樣就很簡單明瞭了,看二進制下標那一列不難發現,其中0表示未選,1表示已選,而且可經過1的位置,知道已選或未選的項目是哪一項。
再看看數組下標與二進制下標的關係,將二進制下標轉爲十進制後,正好就是所需的數組下標。
回頭看看圖中的代碼,上述的取值思路正是forEach內部所幹的事情:
遍歷addon數組中被checked的項,根據其index得出屬於該項的二進制下標,再將遍歷而來的全部二進制下標作OR運算得出最終的二進制下標,後轉爲真正的數組下標,從而得出最終的value值。
經過這種方案,咱們能夠在徹底不關心addonList中的項個數或是每項值的狀況下,得出咱們想要的組合以及取到該組合對應的值,在咱們配置項目的時候只須要留心每一個value的順序便可,不管配置多少項對前端的邏輯也不會產生影響。
將此案例中的addonList個數更改也是同樣可行的,好比有3項的狀況:
選擇狀況 | 值 | 數組下標 | 二進制下標 |
---|---|---|---|
不選 | A-value-0 | A[0] | 000 |
選一 | A-value-1 | A[1] | 001 |
選二 | A-value-2 | A[2] | 010 |
1、二 | A-value-3 | A[3] | 011 |
選三 | A-value-4 | A[4] | 100 |
1、三 | A-value-5 | A[5] | 101 |
2、三 | A-value-6 | A[6] | 110 |
全選 | A-value-7 | A[7] | 111 |
經過此次的表單組件設計,對前端的組件設計有一點點思考:
關於案例代碼,也不肯定你們是否須要。若是有需求的話,後面會補上一個完整版的組件代碼。