iT邦幫忙

2021 iThome 鐵人賽

DAY 28
0
Modern Web

關於 UI 元件你所該知道的事系列 第 28

Day 28 - 實戰演練 — Pagination

https://ithelp.ithome.com.tw/upload/images/20211013/20120754di5QLnG5Aa.png

Pagination

今天要實作的只是一個最基本的 Pagination,而我個人覺得在處理換頁時維持固定長度的邏輯挺有趣的,所以特別在最後一篇實作拿出來講

如果不然很容易不小心點到別頁造成很差的使用者體驗,會容易按錯,像這樣:https://imgur.com/YFSIZQC

https://ithelp.ithome.com.tw/upload/images/20211013/20120754H5p4F18lEN.png

若想要新增功能的話,還可以加「跳至特定頁面的 input」、「顯示頁數」等等的功能。

想先看 Code 或是 Demo 的由此去

Github Repo: ithelp-ui-demo

Live Demo:Pagination

Interface / API

interface PaginationProps {
	disabled?: boolean; // default: false;
	page?: number; // default: 1
	onPageChagne: (page: number) => void;
	pageSize?: number; // default: 10 
	total: number;
	boundaryCount?: number; // defualt: 1
	siblingCount?: number; // default: 1
}
  1. page:現在是第幾頁
  2. onPageChange:換頁的函式,沒有要特別做什麼的話就是把 React 的 setState 丟下去,如果有要邊換頁或換到特定頁數觸發一些函式的話也可以包裝好後丟下去。
  3. pageSize:一頁會呈現幾個元素,越大的話,頁面數量就會越少,因為 頁面數量 = pageSize / total
  4. total:總共有幾頁
  5. boundaryCount:前後會有的數量,預設情況下就像設計稿中只有 1 跟 50,而如果是 2 的話,前後就會是 1 2 跟 49 50,因為是在前後所以取名為 boundary(邊界)。
  6. siblingCount:當前頁面左右會有幾個值,預設情況下就像設計稿中處在第五頁的時候,左右會有 4 跟 6 的頁數,如果值是 2 的話,就會有 3 4 跟 6 7 各兩頁。

要提供更多功能的話,還有以下的 API 可以開

  1. itemRender:客製化每個 Pagination Item。
  2. color, size, shape(圓形、方形), variant(outlined、text) 等等的樣式變化
  3. hidePrevButton 和 hideNextButton:隱藏前後按鈕,這其實就是加個三元判斷隱藏按鈕而已

Component Implement

需要固定 Pagination 長度,避免 CLS。

為此需要有前後預設值、Ellipsis 等等,而我預設 7 個
前後各一,中間三,加兩個 ...
而最前跟最後的時候則是各保留五個

實作思路:

  1. 先處理不足七頁的狀況
  2. minPageCount
    • 處理最少需要的頁數,以維持固定長度
    • 在最前跟最後時,會有 5 + 1 前 or 1 後
    • 在中間時則是 1 + 3 + 1
  3. defaultBoundary for Start and End
    • 最前和最後的邊界頁面
    • aka 下一頁開始就會需要 render 預設以外的頁數
    • start → 4 ,代表第五頁開始會需要原本沒有的第六頁
    • end → 最後一頁 - minPageCount 的前一頁就會需要原本沒有的倒數第六頁
  4. startPags and endPages
    • 預設的首跟尾會有的頁面
    • 當 current 小於等於 start 邊界時,顯示預設的首頁
    • 當 current 大於 start 邊界時,顯示預設的頁數尾頁
  5. currentInMiddle
    • 在預設範圍內的 current 頁面都有 render 出來了
    • 這個在找出不再預設時的當前頁面的 current ,並把它塞到陣列裡
  6. sibling Start and End
    • Current 超出預設時,左右會需要各有一頁
    • 主要是在處理前一頁跟後一頁需要出現的時機點
  7. 最後把他們都塞到要被 map 出來的陣列裡,再透過 filter 去濾掉中間變成 null 的值。

那這邊其實只實作一個比較不能客製化的版本,之後會再重構一次。

https://ithelp.ithome.com.tw/upload/images/20211014/201207540ZE4jIt1N1.png

https://ithelp.ithome.com.tw/upload/images/20211014/20120754qhOADECqxA.png

解說的部分一樣希望之後系列完成後能再回來補上,這邊就先請讀者見諒了,如果有疑問的話可以留言給我,我會馬上解答的!


上一篇
Day 27 - 實戰演練 — Tabs
下一篇
Day 29 - 實戰演練 — 元件單元測試
系列文
關於 UI 元件你所該知道的事30

1 則留言

1
Taiming
iT邦新手 4 級 ‧ 2021-10-14 10:27:05

學習了!

我才跟著你每天實作一個元件學習了!每天實作真的太強大了!

Taiming iT邦新手 4 級 ‧ 2021-10-15 09:03:46 檢舉

話說我在做的時候還真的沒有仔細想到這個:

處理換頁時維持固定長度,如果不然很容易不小心點到別頁造成很差的使用者體驗,會容易按錯

回想起來還真的蠻容易按錯的(囧

但想跟P大請教,如果頁數不足,是不是就沒有辦法固定長度了呢?或是是否有建議的做法?

沒事,Ant Design 也沒有處理這個 UX!XD
這個問題的話,其實在頁數不足的情況下,長度就會根據現在是幾頁而顯示多長。
以操作情境來解釋的話,就是我們會在換頁到第五頁的時候按錯頁數,是因為預期是換頁按鈕的地方因為多了 Ellipsis 而把換頁按鈕往後推,進而點成某頁的按鈕。
但如果沒有超過預設的頁數(如範例中是五頁,超過六頁才會有 Ellipsis),就不會出現使用者預期是換頁按鈕而變成頁數按鈕的情境。
因此,長度的部分會根據頁數有 「一頁~超過五頁」 的六種固定長度!
我是這樣去設計的!

我要留言

立即登入留言