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

解说的部分一样希望之後系列完成後能再回来补上,这边就先请读者见谅了,如果有疑问的话可以留言给我,我会马上解答的!


<<:  Day28 小乌龟自动掘井挖隧道

>>:  [Day 28]从零开始学习 JS 的连续-30 Days---BOM-浏览器物件模型(下)

[Day12] Android - Kotlin笔记:JetPack - Fragments在Navigation中的参数传递(Safe Args)

Fragments在Navigation中的参数传递 - SafeArgs 继上篇我们得知如何运用N...

第02天 - 环境建立(上)

前言: 印象中第一次写网页时,我连 Sublime text 的运作方式都很不习惯,因为每次打开时它...

Day-25 尚未开始便已衰败、策略错误的 XBOX ONE

为了与 SONY 的 PS4 相抗衡、基於过去的策略、微软也选择在几乎相同的时间发布了他们的新主机 ...

[自学笔记] URL Encoding

URL Encoding(URL编码) URL 编码将字符转换为可以通过 Internet 传输的格...

Day 18 — To Do List (5) 新增 To Do Event

昨天我们快乐 (?) 的把资料 render 到网页上(虽然会有点 Delay,对 UX 不好…不过...