vue_分頁元件
封裝的分頁元件的結構如下:
1.基本分頁功能
(1)將陣列分為指定大小的多個小陣列的chunk方法
export function chunk(arr=[],size=1){
if(arr.length===0) return [];
return arr.reduce((total,currentValue)=>{
if(total[total.length-1].length===size){
total.push([currentValue]);//當小陣列的長度與指定大小size相等時,重新建立一個小陣列
}
else{
total[total.length-1].push(currentValue);//當小陣列的長度小於指定大小size時,就往該小陣列中新增資料
}
return total;
},[[]])//[[]]是為了將分割後的小陣列仍保留在一個大陣列中
}
2.頁碼顯示策略
為了方便地跳轉到任意頁碼,卻又不至於在頁面中顯示太多頁碼,頁碼不是始終全部顯示出來的,而是在頁碼少時全部顯示,頁碼多時只顯示部分頁碼。這就存在顯示策略問題。
(1)我們從當前頁碼出發,比如模組中當前頁碼是第5頁:
那麼以該頁碼為中心,兩邊顯示一定的頁碼,比如兩邊各顯示2頁;
另外首頁和尾頁需要始終顯示出來,方便回到首頁和跳轉到尾頁;
首頁到第3頁中間的頁碼以及第7頁到頁尾的頁碼都隱藏起來,並且支援點選左/右更多按鈕,快捷跳轉多頁(比如5頁)的功能。
(2)如果只存在8頁,則去掉右邊的更多按鈕:
(3)如果當前頁碼在第4頁,則去掉左邊的更多按鈕,顯示右邊的更多按鈕:
簡述如下:
(1)首頁和尾頁需要始終顯示出來(如果只有1頁則不顯示尾頁);
(2)除首尾頁之外,當前頁碼左右最多隻顯示2頁(共5頁);
(3)其它頁碼摺疊起來,用更多按鈕(…)代替。
3.分頁器
(1)分3步實現分頁器功能:
1)實現首尾翻頁
2)實現快捷分頁
3)實現分頁按鈕組
(2)增加左/右按鈕更多按鈕的翻頁功能
有了首尾頁的翻頁還不夠,還需要繼續完善更多按鈕的快捷翻頁功能。
先梳理下更多按鈕的顯示邏輯:
1)中間按鈕一共5頁,加上首尾按鈕2頁,一共7頁,也就是說只有大於7頁,才有可能顯示更多按鈕;
2)左右更多按鈕會隨著當前頁碼的不同而顯示或隱藏,以第4頁和倒數第4頁為界;
3)當頁碼大於第4頁時,應該顯示左邊更多按鈕;
4)當頁碼小於倒數第4頁,都應該顯示右邊更多按鈕。
//Pager元件程式碼:
<template>
<ul class="pager">
<!-- 首頁-->
<li class="number"
:class="{active: this.current===1}"
@click="setPage(1)">1</li>
<!-- 左邊更多-->
<li class="more left"
v-if="totalPage>centerSize+2 && current-centerSize/2-1>1"
@click="setPage(current-jumpSize)">...</li>
<!-- 中間頁碼-->
<li class="number"
v-for="(page,index) in centerPages"
:class="{active: current===page}"
:key="index"
@click="setPage(page)">{{ page }}</li>
<!-- 右邊更多-->
<li class="more right"
v-if="totalPage>centerSize+2 && current+centerSize/2+1<totalPage"
@click="setPage(current+jumpSize)">...</li>
<!-- 最後一頁-->
<li class="number"
v-if="totalPage!==1"
:class="{active: this.current=== totalPage}"
@click="setPage(totalPage)">{{ totalPage }}</li>
</ul>
</template>
<script>
export default {
name: "Pager",
props:{
totalPage:Number,//資料總頁數
defaultCurrentPage:Number,//預設當前頁碼
//中間頁碼數預設為5
centerSize:{
type:Number,
default(){
return 5;
}
},
jumpSize:{
type:Number,
default(){
return 5;
}
}
},
computed:{
// 中間頁碼計算
centerPages(){
let centerPage=this.current;
// 若當前頁面大於this.current+2(以current為中心右邊加兩頁) +1(尾頁)>this.totalPage,則取this.totalPage-3為中心
if(this.current>this.totalPage-3){
centerPage=this.totalPage-3;//注意這裡是centerPage,不是this.current
}
// 若當前頁面小於或等於4,則取4為中心
if(this.current<4){
centerPage=4;
}
if(this.totalPage<=this.centerSize+2){
// 總頁碼較少時,則全部顯示出來
const centerArr=[];
for(let i=2;i<this.totalPage;i++){
centerArr.push(i);
}
return centerArr;
}
else{
// 總頁數較大時,只顯示中間centerSize個頁碼
const centerArr=[];
for(let i=centerPage-2;i<=centerPage+2;i++){
centerArr.push(i);
}
return centerArr;
}
}
},
data(){
return{
// 因為不可以直接修改props傳過來的值,所以在data中用current儲存props中預設頁面頁數defaultCurrentPage的值,用watch監聽props中defaultCurrentPage值的改變
// (前一頁、後一頁按鈕被點選時,會傳入新的值,但是data中的current不會更新,用watch監聽並賦新的值,可解決該bug)
current:this.defaultCurrentPage,
}
},
watch:{
// 監聽props中defaultCurrentPage值的改變,更新current的值
defaultCurrentPage:function(newValue,oldValue){
this.current=newValue;
}
},
methods:{
// 上一頁、下一頁按鈕被點選時,頁碼發生改變,且要傳出被點選的頁碼
setPage(page){
// 左邊越界
if(page<1) this.current=1;
// 右邊越界
else if(page>this.totalPage){
this.current=this.totalPage;
}
// 正常情況
else{
this.current=page;
}
// 發出pager中頁碼被改變的事件
this.$emit('change',this.current);
},
}
}
</script>
<style scoped>
ul{
list-style: none;
height: 32px;
}
ul li{
float: left;
width:30px;
height:30px;
line-height: 30px;
margin:0 8px 0 0;
padding:0 6px;
text-align: center;
border:1px solid #d9d9d9;
border-radius:2px;
}
.active{
border:1px solid #7d3990;
}
.more left:hover, .more right:hover{
background: #7d3990;
}
</style>
//Pagination程式碼:
<template>
<div id="pagination">
<!-- 前一頁按鈕-->
<input class="btn-prev" type="button" value="<" @click="setPage(current-1)">
<!-- 分頁器-->
<pager :total-page="totalPage" :default-current-page="current" @change="pageChange"></pager>
<!-- 後一頁按鈕-->
<input class="btn-next" type="button" value=">" @click="setPage(current+1)">
</div>
</template>
<script>
import Pager from "./Pager";
export default {
name: "Pagination",
components:{
Pager
},
props:{
// 預設當前頁碼
defaultCurrentPage:{
type:Number,
default(){
return 1;
}
},
// 預設每頁資料的條數
defaultPageSize:{
type:Number,
default(){
return 10;
}
},
// 資料的總條數
total:{
type:Number,
default(){
return 100;
}
},
},
data(){
return{
current:this.defaultCurrentPage
}
},
computed:{
// 計算資料總頁數
totalPage(){
return Math.ceil(this.total/this.defaultPageSize);
}
},
methods:{
// 上一頁、下一頁按鈕被點選時,頁碼發生改變,且要傳出被點選的頁碼
setPage(page){
// 左邊越界
if(page<1)this.current=1;
// 右邊越界
else if(page>this.totalPage){
this.current=this.totalPage;
}
// 正常情況
else{
this.current=page;
}
// 發出事件,讓外部知道頁碼改變了
this.$emit('change',this.current);
},
// 接收pager中發出的改變頁碼事件,並再次傳送出去
pageChange(page){
this.$emit('change',page);
}
}
}
</script>
<style scoped>
#pagination{
display: flex;
}
.btn-prev, .btn-next{
width:30px;
height:30px;
line-height: 30px;
margin:0 8px 0 0;
padding:0 6px;
text-align: center;
border:1px solid #d9d9d9;
border-radius:2px;
background: #fff;
}
</style>
參考:https://juejin.im/post/6844904151730782221#heading-30
相關文章
- 分頁元件原始碼分享元件原始碼
- Android分頁元件Paging簡單使用Android元件
- Flutter 分頁功能表格控制元件Flutter控制元件
- VUE_入門講義Vue
- layui 分頁元件 ,重新整理後返回第一頁問題UI元件
- 如何寫一個簡單的分頁元件(原理)元件
- rest認證元件,許可權元件,頻率元件,url註冊器,響應器元件,分頁器元件REST元件
- SAP UI5 列表控制元件分頁顯示資料時,如何自定義分頁大小UI控制元件
- [Django高階之批量插入資料、分頁器元件]Django元件
- 比Django官方實現更好的分頁元件+Bootstrap整合Django元件boot
- mysql分頁-limit offset分頁MySqlMIT
- 100行程式碼實現一個vue分頁元件行程Vue元件
- 在Vue3中使用Element-Plus分頁(Pagination )元件Vue元件
- Android官方架構元件Paging:分頁庫的設計美學Android架構元件
- C/C++ Qt Tree與Tab元件實現分頁選單C++QT元件
- flask 分頁 | 翻頁Flask
- Django框架之drf:7、認證元件,許可權元件,頻率元件,過濾的多種用法,排序,分頁,Django框架元件排序
- php 分頁 分頁類 簡單實用PHP
- C++ Qt開發:Tab與Tree元件實現分頁選單C++QT元件
- 分頁器
- Flask——分頁Flask
- 集合分頁
- php 分頁PHP
- 分頁案例
- Lavarel Ajax 分頁時 獲取分頁資訊
- Android官方架構元件Paging-Ex:為分頁列表新增Header和FooterAndroid架構元件Header
- 商品分類元件元件
- Django的分頁Django
- jq寫分頁
- Spring JPA 分頁Spring
- 日誌、分頁
- 分段與分頁
- REST framework:分頁RESTFramework
- 如何高效分頁
- php分頁類PHP
- ES 分頁方案
- 讀寫分離 & 分庫分表 & 深度分頁
- Spring專案處理分頁(邏輯和物理分頁)Spring