「技術分享」以Antd為例,快速打通UI元件開發的任督二脈
theme: condensed-night-purple highlight: atelier-heath-light
前言
猶記得,我還是一個初入職場的新人,出去面試總會被問到會不會元件開發的問題。當時專案開發都使用現成的UI元件,最初用Element UI,後來換成了Antd。無論換哪種元件,都幫助節省了大量的開發時間,自己平時元件開發,最多就進行一些簡單的標題、彈窗、表格的二次封裝。總之就是,元件開發的“道行”尚淺,所以面試的時候底氣略微不足。
經過歲月的沉澱,經驗的累積,自己開發一套UI元件已經不是什麼困難事的時候。開啟Antd的原始碼,想研究一下,Antd的技術團隊,是怎麼實現我們在官網看到的這些元件的。
講一個我之前年少無知的往事。最開始使用Element,還挺困惑的。就琢磨著餓了麼不是送外賣的嘛,怎麼還提供上技術的元件庫了?後來才知道,人家的技術團隊也非常非常的厲害。
「寫過通用元件嗎?」
這道面試題的關鍵在於,通用元件怎麼寫。
系統特性
現今,UI元件庫豐富且成熟,所以可能覺得日常開發中,通用元件會寫的很少,其實不然。
每個系統,無論是業務特性、互動特性還是UI特性,都可以整理出一部分通用元件,比如標題、頁面佈局、列表、可編輯表格、模糊搜尋框等
以列表為例
Antd有現成的Table元件,但是我們實際開發中,一般列表管理頁是帶搜尋項以及資料展示的,有可能還帶搜尋重置按鈕或者搜尋匯出按鈕。
所以通用元件就有用武之地了,一次封裝,千千萬萬的列表管理頁面就都可以用一個元件搞定了。
```js {!resetAble && ( )} {exportable && ( )}
; ``` ## 功能通用 已知日常開發中的部分功能確實可以做成通用元件,那麼怎麼界定通用的邊界呢? 通用性過高會導致程式碼過於複雜,通用性過低,開發效率會變低。我一般會觀察以下兩點: 1. 用到這個功能的時候,和業務可能關係不大,UI或者互動操作,在任何業務線下都需要這樣設計,比如可編輯表格。 2. 使用頻率,這個要加一點對未來業務發展的預判。比如搜尋項中的省份和城市,需要實現模糊搜尋匹配的功能。 未來無論怎麼樣的業務,只要有省份、城市這兩項基本都需要這個功能。 ```js ; ``` ## 引數設計 通用元件,差異的部分,一般在功能設計的時候會通過外部傳參區分或者控制。所以開發通用元件,引數設計是重要的一個環節。 如果剛開始不是很擅長設計引數,可以參考Antd的引數設計,Antd的元件豐富且功能強大,所以引數考慮的也很周全。邊學邊練,效果更佳。 如圖為Antd的Input輸入框元件「平平無奇」的引數:  # Antd元件功能賞析 電影有精彩片段賞析,Antd的元件很豐富,如果一一列舉,詳細介紹,可能我要寫到下個月,所以我選了幾個常見且基礎的元件,來看看Antd是怎麼設計這些元件的。 官網指路☞[Ant Design](https://ant.design/components/overview-cn/) ## 賞析前準備 學習第三方元件之前,不能盲目看程式碼,可能會找不到重點或者被大量的邏輯繞暈。我一般學習之前先做三方面準備: - 先明確元件要實現什麼功能,比如輸入框是否不可操作,是否回顯資料等; - 然後看元件引數,把引數分為控制UI佈局、控制內容展示、控制操作功能等幾種;比如通過disabled的值控制輸入框是否可以操作,通過設定value的值進行資料回顯等; - 最後去思考這些引數怎麼實現具體的功能,就比較容易想清楚了。 ## Grid 柵格 柵格化佈局,基於行(row)和列(col)來定義資訊區塊,可以將區域24等分。通過 row 在水平方向建立一組 column,內容放置於 col 內。 ### 展示層 看col檔案中這三行程式碼,和各種style、className變數。不難發現,柵格化佈局主要是通過元件引數對樣式的控制來實現的。 ```js return (
{children}
);
```
### 佈局設計
結合引數說明和程式碼分析,可以大致總結出柵格佈局的設計如下:
1.柵格元件基於 Flex 佈局。
2.柵格的佔位格數,也是它的寬度,樣式實現時使用百分比,比如span的值為6時,24等分之後,它的百分比是25%。
```
.ant-col-6 {
display: block;
flex: 0 0 25%;
max-width: 25%;
}
```
3.區塊間隔格數的值實際上是設定的padding值的2倍,是相鄰兩個模組的間距之和。所以程式碼中進行了除以2的處理。
```
if (gutter && gutter[0] > 0) {
const horizontalGutter = gutter[0] / 2;
mergedStyle.paddingLeft = horizontalGutter;
mergedStyle.paddingRight = horizontalGutter;
}
```
4.響應式佈局,支援六個響應尺寸:xs、sm、md、lg、xl、xxl。引數支援多型別可以是number型別,也可以是Object型別。使用typeof判斷引數型別。
```
if (typeof propSize === 'number') {
sizeProps.span = propSize;
} else if (typeof propSize === 'object') {
sizeProps = propSize || {};
}
```
佈局功能分析告一段落,柵格元件賞析也就收工了。
## Steps 步驟條
我們來看看步驟條的功能。
- 步驟條狀態,已完成、進行中、未開始、執行錯誤。
- 兩種展示方式,橫向和縱向。
- 不同展示型別,數值類、自定圖示類、點狀類。
- 內容展示,標題、子標題、詳情描述。
### rc-steps
我在看Antd的原始碼時發現,有些元件底層用的第三方[react-component](https://github.com/react-component)中的元件。當然這個元件庫也是屬於Antd的。所以想研究Steps元件的功能,需要翻另一個元件庫的程式碼[react-componentr/steps](https://github.com/react-component/steps)。
```js
import RcSteps from 'rc-steps';
```
### 步驟條狀態
既可以通過status直接指定當前步驟狀態,也可以通過對比current和步驟的數值確定步驟的狀態。
```js
const stepNumber = initial + index;
if (status === 'error' && index === current - 1) {
childProps.className = `${prefixCls}-next-error`;
}
if (!child.props.status) {
if (stepNumber === current) {
childProps.status = status;
} else if (stepNumber < current) {
childProps.status = 'finish';
} else {
childProps.status = 'wait';
}
}
```
### 展示型別
步驟條支援多種不同的展示型別,程式碼實現上主要是通過條件語句判斷。
- 點狀型別,支援自定義展示。當點狀步驟條引數progressDot的值是函式型別時,會使用傳入的值;否則使用內部定義的點狀展示內容。
- 自定義圖示,引數icon表示步驟圖示的型別,當它有值的時候,步驟條會顯示成它的值。有兩個特殊的圖示:成功狀態、失敗狀態,這兩個狀態的圖示如果使用元件時沒有進行自定義,會取內部定義的圖示。
- 預設型別,放到條件判斷最底層,當其他判斷條件的引數沒有值時,步驟條會展示內部定義的預設型別。
**條件判斷**

**內部定義的成功和失敗的圖示**
```js
const icons = {
finish:
「其他文章」
- await-to-js 原始碼分析,體驗一把捕獲異常的優雅
- CSS偽類的第三集,原來偽類也可組CP
- 從:is()說起,開啟CSS偽類第二集
- 一組純CSS開發的聊天背景圖,幫助避免發錯訊息的尷尬
- 「CSS特效」我的發呆專屬,反覆解鎖手機螢幕
- 「技術分享」以Antd為例,快速打通UI元件開發的任督二脈
- 「功能實現」我封裝了一個表單元件,感覺離財富自由又近了一步
- 「經驗總結」高效開發,老程式碼可以這樣動
- 前端開發提效小技巧之業務功能篇
- 人生有忙忙碌碌,也有詩和遠方 | 2022年中總結
- 【端午節】新奇體驗,我用react實現網頁遊戲的全過程(包括規則設計)
- 【暑假記憶】消暑神器,我用CSS復刻了一個遊戲機
- 突圍?我願稱之為向上的攀登者
- 【孟夏之遇】望孟夏之短夜兮,螢星相伴
- 【技術學習】SVG-邊學邊做
- 【TS實踐】自己動手豐衣足食的TS專案開發
- 【碼上掘金】通過FileReader讀取Excel檔案內容
- 【Taro開發】四月芳菲,Taro觀賞指南
- 【Node.js】青梅煮酒,聊聊zlib壓縮
- 【知識點】關於iframe跨域通訊