Hello好久不見。跳槽之後一直沒什麼時間總結記錄這段時間的見聞或實踐,好不容易擠出點時間,今天想記錄一下最近的一個元件設計&開發歷程,該元件的開發環境是小程式,但是我認為這個思維是通用的~
本文可能涉及內容--
- 需求簡介
- 位運算與表單元件的結合
- 元件設計小結
需求簡介
我們大概需要完成這樣一個表單元件↓↓
由圖大致可以判斷,我們應該將此元件拆成兩塊,一個是tab選項區,一個是下方的附加選項區。
為什麼需要分拆?
-
最主要的原因是專案自身原因,之前就有tab的元件,我們可以直接引用。
-
當然,就算我們自身專案沒有這個元件,我也是建議拆分開來,因為在表單的開發中,這種tab選擇的形式可以說太常見了,拆分開來肯定是有益的,並且它的功能十分單一,很適合作為一個獨立元件。
如何用資料結構描述元件?
靜態結構大概明瞭,那麼我們應該怎麼用資料來描述這個元件呢?接下來就來考慮一下元件的資料結構,開始之前先明確幾個前提--
「tab數目不定、tab與附加項內容有聯動、附加項數目不定」
上圖是我在第一版中構思的資料結構,制定該規則的原因如下--
-
由於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 |
一、二 | A-value-3 | A[3] | 011 |
選三 | A-value-4 | A[4] | 100 |
一、三 | A-value-5 | A[5] | 101 |
二、三 | A-value-6 | A[6] | 110 |
全選 | A-value-7 | A[7] | 111 |
元件設計總結
通過這次的表單元件設計,對前端的元件設計有一點點思考:
- 獨立
- 元件功能單一,radio就應該負責radio選擇,不要加上一些與業務相關的邏輯或文案。
- 元件儘量不要過於複雜,既然分拆了元件就不要想著一個元件能完成所有的事情。
- 可複用
- 在設計元件的時候除了滿足當前的需求,最好還要考慮其通用性。倘若發現它不具有通用性,就不如寫在業務裡,不需要單獨抽離。
- 當然,在設計元件時不可能要求使用元件的場景要百分百一致,讓元件的適應、擴充能力變強,有助於元件的健壯。
- 中立
- 儘可能的少於業務耦合--保證元件中立。
- 這一點看看就好,一般都是骨感的現實:)
- 易用
- 儘量能做到使用者只需要考慮輸入以及輸出。
關於案例程式碼,也不確定大家是否需要。如果有需求的話,後面會補上一個完整版的元件程式碼。