凡人修React|新手練氣築基必備! 抖音商城[商品資訊卡元件]開發
theme: healer-readable
持續創作,加速成長!這是我參與「掘金日新計劃 · 6 月更文挑戰」的第1天,點選檢視活動詳情
前言
React
- 宣告式
:React 使建立互動式 UI 變得輕而易舉。為你應用的每一個狀態設計簡潔的檢視,當資料改變時 React 能有效地更新並正確地渲染元件。
- 元件化
:建立擁有各自狀態的元件,再由這些元件構成更加複雜的 UI。元件邏輯使用 JavaScript 編寫而非模版,因此你可以輕鬆地在應用中傳遞資料,並使得狀態與 DOM 分離。
本次通過開發抖音商城商品資訊列表元件
,走進React的懷抱。
不多說,先看效果gh-pageshttp://hunag-mouren.github.io/dy_mall/
再看專案架構
1. 元件設計與功能需求
1.1 元件設計
首先將商品資訊卡列表元件
細化,分為頭部tabs切換部分
和資訊卡列表部分
,其中資訊卡列表部分包含有商品資訊卡項
、直播資訊卡項
、影片資訊卡項
,且各項資訊卡項包含兩種狀態,分別為資料載入前的狀態
和資料載入後的狀態
。即:
- 頭部tabs切換部分
- 商品資訊卡項
- 直播資訊卡項
- 影片資訊卡項
如下圖所示。 基於以上我們有如下元件藍本的程式碼:
1.2 功能需求
就實際應用場景而言,有如下功能應當實現:
- Tabs切換跟隨點選顯示高亮並激活
- 資訊卡列表部分跟隨tabs切換顯示相應內容
- 第一進入某個資訊卡資料載入時應當顯示資料載入前的狀態
,後面再進入該項不再顯示資料載入前的狀態
- 圖片懶載入的實現
- 當滾動到底部後可以載入新的資料
2. 元件實現
2.1 Tabs切換部分實現
Tabs切換部分將使用antd-mobile中的Tabs元件來實現,其選項卡面板為Tabs.tab。其中本次涉及屬性有:
Tabs屬性 - activeKey:為當前啟用面板的key值 - onChange:切換面板時的回撥,傳入的引數為將被選中Tab的key值
Tabs.Tab屬性 - key:和Tabs的activeKey對應 - title:選項卡的標題名字 由以上可知,當我們選中的面板被啟用,則Tabs中的activeKey屬性值就會變成對應選中面板Tab的key值,憑此會為為Tab面板新增“adm-tabs-tab-active”的類名(如下圖所示),進而被選中時高亮。
那我們只需要把activeKey值修改為我們將選中的面板的key值就可以啟用它,這時我們就可以藉助onChange屬性,在回撥函式中修改activeKey的值。但是activeKey作為屬性不好在回撥函式中操作,那不妨利用一箇中間變數,修改中間變數的值,再把中間變數的值傳給activeKey。考慮到後續在切換面板時要顯示相應的內容,那麼我們這裡使用State Hook,利用useState()方法返回的state值作為中間變數以及更新state值的函式來修改該值,以達到更新activeKey值得目的,進而實現Tabs切換。實現程式碼如下。
考慮到我們當前定義的從useState()方法解構出來的[activityKey,setActivityKey]
不僅僅只會在GoodCardList元件中被使用,我們應當將其放在父元件當中。於是我們通過父元件給子元件傳參
,讓GoodCardList元件得到這些屬性。程式碼將修改如下。
至此Tabs頭部切換完成,效果如下。
2.2 資訊卡列表部分實現
由上文可知資訊卡列表部分其實是由商品資訊卡項
、直播資訊卡項
、影片資訊卡項
組成,就實際情況而言可視該三項內容為通用元件
。這三項異曲同工,不妨就以商品資訊卡為例。這時我們需要進行資料請求,資料方面我們通過線上介面工具fastmock組織,fastmock可以讓你在沒有後端程式的情況下能真實地線上模擬 ajax 請求,實現前後端分離。然後我們通過axios
進行請求資料,axios是一個基於promise 的 HTTP 庫。同時使用async函式與await操作符同步化獲取資料過程。
在src目錄下新建一個api資料夾,在其之下新建request.js檔案,該檔案用於做請求方面的工作,我們資料請求的程式碼就封裝在其中。
資料請求一般都在頁面級別元件,請求到的資料通過引數傳遞給子元件。這時我們就要請出Effect Hook,它可以告訴React元件需要在渲染後執行某些操作。React 會儲存你傳遞的函式(我們將它稱之為 “effect”),並且在執行DOM更新之後呼叫它。預設情況下,它在第一次渲染之後和每次更新之後都會執行。但我們可以通過給它的第二引數(是個陣列)來控制它,如果這個數組裡的內容在兩次重渲染之間沒有發生變化,就可以通知 React 跳過對這個effect 的呼叫;如果發生了改變就會再次對這個effect進行呼叫。那麼我們在切換不同面板時需要請求不同的內容,我們就可以把請求資料的過程放在Effect中,並通過前文的定義的State中的activityKey來實現面板切換時是否需要請求資料。
GoodsCardList元件內接收資料後,根據資料生成(map)資訊卡列表裡各項內容,同時別忘了在map列表裡的資料內容時,要給每一項新增一個獨一無二的key值
。
因為每當一個列表重新渲染時,React 會根據每一項列表元素的 key 來檢索上一次渲染時與每個 key 所匹配的列表項
。如果 React 發現當前的列表有一個之前不存在的 key,那麼就會創建出一個新的元件。如果 React 發現和之前對比少了一個 key,那麼就會銷燬之前對應的元件。如果一個元件的 key 發生了變化,這個元件會被銷燬,然後使用新的 state 重新建立一。(這裡我在fastmock組織的資料中給每條資料都自動生成了一個獨一無key)
商品資訊卡項元件的實現
至此商品資訊卡列表元件開發過半,來看看目前效果。
2.3 增加loading狀態
發現每次切換面板的時候,頁面需要過一段時間才會顯示內容,使用者體驗不好。這時由於資料還在請求中,資料請求完成後才渲染出該列表內容,那麼我們這時需要新增一個loading狀態,在資料請求數顯示loading狀態的頁面內容。
增加一個新的State Hook ,[loading,setLoading]=useState(false)
來控制是否需要loading,[requestKey,setRequestKey]=useState([])
來記錄某個面板是否被訪問過,訪問過後再訪問不會再出現loading狀態。
並給商品資訊卡項
、直播資訊卡項
、影片資訊卡項
加入loading狀態時顯示的框架內容。其種loading狀態顯示的框架屏內容使用了antd-mobile的Skeleton,它可以在需要等待載入內容的位置提供一個佔位圖形組合。具體如下
看看現在的效果
2.4 實現圖片懶載入
考慮實際應用場景,我們不妨在加上懶載入,當圖片未出現在可視區域是用佔位圖代替,進入可視區域顯示圖片 使用IntersectionObserver建立觀察器例項,通過檢查圖片是否出現在可視區域,來實現懶載入。
效果如下。
2.5 滾動底部自動載入資料
實現滾動到底部自動載入更多資料
這是使用到antd-mobil的InfiniteScroll,它有如下屬性
- hasMore:是否還有更多內容
- loadMore:載入更多的回撥函式
- threshold:觸發載入事件的滾動觸底距離閾值,單位為畫素
使用者想看到新的資料時,可以上滑頁面自動載入資料。當 hasMore
屬性為 true
時,使用者頁面滾動到底部 threshold
(預設為 250px)時無限滾動元件會呼叫定義的 loadMore
函式。程式碼如下:
並配和上文的requestKey來實現當首次進入某個面板未請求資料前不提供該滾動元件,否則在第一次進入某個面板時該滾動元件會先執行。來看下當前效果吧。
可以看到當滾動到底部時會去請求資料,並將根據新資料建立新的資訊卡項,當然是通過資訊卡項中的key來決定是否要新建,像之前就建立好的資訊卡項在這次就不會新建了。
總結
至此該商品資訊列表元件
開發就完成了,另外還有三個通用元件
,商品資訊卡項元件
、直播資訊卡項元件
、影片資訊卡項元件
。這四個元件在以後都會經常被用到的。接下來對本次元件開發過程進行總結
:
- State Hook
:它讓我們在 React 函式元件上新增內部 state,通過useState()方法我們可以定義當前 state 以及更新 state 的函式。
- Effect Hook
:它可以告訴 React 元件需要在渲染後執行某些操作。React 會儲存你傳遞的函式(我們將它稱之為 “effect”),並且在執行 DOM 更新之後呼叫它。預設情況下,它在第一次渲染之後和每次更新之後都會執行。但同時,我們可以給它的第二個引數傳入一個數組,當數組裡的內容發生改變時effectc才會再執行。
- key值
:在map生成新的元件時,記得新增獨一無二的key,因為每當一個列表重新渲染時,React 會根據每一項列表元素的 key 來檢索上一次渲染時與每個 key 所匹配的列表項。如果 React 發現當前的列表有一個之前不存在的 key,那麼就會創建出一個新的元件。如果 React 發現和之前對比少了一個 key,那麼就會銷燬之前對應的元件。如果一個元件的 key 發生了變化,這個元件會被銷燬,然後使用新的 state 重新建立一份。
- styled-components
:css in js 。styled-components 為您的樣式生成唯一的類名。您永遠不必擔心重複、重疊或拼寫錯誤。很難知道類名是否在您的程式碼庫中的某處使用。styled-components 讓它變得顯而易見,因為每一個樣式都與特定的元件相關聯。如果元件未使用(工具可以檢測到)並被刪除,則其所有樣式都會隨之刪除。根據元件的 props
或全域性主題調整元件的樣式簡單直觀,無需手動管理數十個類。本次就通過props將背景圖片自定義引數化傳入。
- antd-mobile
:移動端的常用元件庫,比如本次用的Tabs
,Skeleton
,Space
。用它就對了。
font-awesome
:Font Awesome 字型為我們提供可縮放向量圖示,它可以被定製大小、顏色、陰影以及任何可以用CSS的樣式。用它就對了
Next
商品資訊卡列表元件開發完畢,下一步將會開始搭建商城主頁面
,並將Router
安排上。
本次專案地址 :http://github.com/hunag-mouren/dy_mall.git
gh-pages:http://hunag-mouren.github.io/dy_mall/