「技術分享」以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跨域通信