不想使用第三方庫,只想使用一個分頁器,那么就簡單的實現一個,效果如下:

1.使用方式:
<custom-pagination *ngIf="enterpriseList.length" [fastTurnBtn]="false" [totalPage]="paginationParams.totalPages" [maxSize]="paginationParams.maxSize" [(ngModel)]="paginationParams.currentPage" (changePage)="changePage($event)"> </custom-pagination>
2.可配置項:
- fsatTurnBtn:是否顯示首頁和末頁
- turnBtn:是否顯示上下翻頁
- maxSize:最多顯示幾頁
- totalPage:總頁數
- moreBtn:是否顯示省略號提示更多分頁
3.實現方案:
先上代碼,這里使用啦ngModel實現自定義組件的數據雙向綁定,可以看上一篇隨記的介紹:
// custom-pagination.ts
import { Component, OnInit, Input, Output, EventEmitter, OnChanges, forwardRef } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; @Component({ selector: 'custom-pagination', templateUrl: './pagination.component.html', styleUrls: ['./pagination.component.css'], providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => PaginationComponent), multi: true }] }) export class PaginationComponent implements OnInit, OnChanges { constructor() { } @Input() totalPage: any; @Input() maxSize: any = 5; @Input() moreBtn: Boolean = true; @Input() turnBtn: Boolean = true; @Input() fastTurnBtn: Boolean = true; @Output() currentPageChange: EventEmitter<Number> = new EventEmitter; @Output() changePage: EventEmitter<Number> = new EventEmitter; private currentPage = 1; showPageList: Array<number> = []; showEndPage = 0; showBeginPage = 0; showLeftMoreStatus = false; showRightMoreStatus = false; ngOnInit() { } ngOnChanges () { // 異步獲取的數據,在ngOnChange里監聽數據變化后再處理分頁 this.initPages(); } currentChange() { this.currentPageChange.emit(this.currentPage); } goToPage (page) { if (page && this.currentPage !== page) { this.currentPage = page; this.changePageHandle(); } } prevNextPage (page) { console.log(this.currentPage) if (this.totalPage < 2) { return; } let pageNum; if (page === '上一頁') { pageNum = this.currentPage === 1 ? this.currentPage : this.currentPage - 1; } else { pageNum = this.currentPage === this.totalPage ? this.currentPage : this.currentPage + 1; } if (pageNum !== this.currentPage) { this.currentPage = pageNum; this.changePageHandle(); } } leftMoreClick () { // 左更多按鈕點擊后處理當前顯示的分頁 const startPage = this.showBeginPage - this.maxSize; const endPage = startPage + this.maxSize; this.currentPage -= Math.ceil((endPage - startPage) / 2); this.changePageHandle() } rightMoreClick () { // 右更多分頁按鈕點擊后處理當前顯示的分頁 let startPage; if ((this.showEndPage + this.maxSize) < this.totalPage) { startPage = this.showEndPage + this.maxSize; } else { startPage = this.totalPage - this.maxSize; } const endPage = startPage + this.maxSize; this.currentPage += Math.ceil((endPage - startPage) / 2); this.changePageHandle() } formatPages () { // 操作頁碼后處理需要顯示的新頁碼數據 if (this.totalPage > this.maxSize) { const formatRightPage = this.showEndPage - Math.ceil(this.maxSize / 2); // 需要向后處理顯示分頁數據的分界點 const formatLeftPage = this.showBeginPage + Math.floor(this.maxSize / 2); // 需要向前處理顯示分頁數據的分界點 let startPage; // 需要顯示的開始頁碼 if (this.currentPage > formatRightPage || this.currentPage < formatLeftPage) { startPage = this.currentPage - Math.floor(this.maxSize / 2) > 0 ? this.currentPage - Math.floor(this.maxSize / 2) : 1; this.showBeginPage = startPage; this.showEndPage = (startPage + this.maxSize) < this.totalPage ? (startPage + this.maxSize) : this.totalPage; if (this.showEndPage - this.showBeginPage <= this.maxSize) { // 如果處理后顯示的分頁數量少於maxSize,處理需要顯示的開始頁碼滿足maxSize startPage = this.showEndPage - this.maxSize; this.showBeginPage = startPage; } this.handlePagesData(startPage, this.showEndPage); } } console.log(this.showPageList) } initPages () { // 根據傳入的參數初始化頁碼 if (this.totalPage > this.maxSize) { this.maxSize--; const startPage = this.currentPage; this.showBeginPage = startPage; this.showEndPage = startPage + this.maxSize; this.handlePagesData(startPage, this.showEndPage); } else { this.showBeginPage = this.currentPage; this.showEndPage = this.totalPage; for (let i = 1; i <= this.totalPage; i++) { this.showPageList.push(i) } } this.showPagesMore(); } handlePagesData (begin, end) { // 循環生成要顯示的頁碼數據 this.showPageList = []; for (let i = begin; i <= end; i++) { this.showPageList.push(i) } } showPagesMore () { // 判斷是否滿足顯示向左向右更多分頁按鈕的條件 if (this.currentPage > this.maxSize * 2) { this.showLeftMoreStatus = true; } else { this.showLeftMoreStatus = false; } if (this.showEndPage < this.totalPage) { this.showRightMoreStatus = true; } else { this.showRightMoreStatus = false; } } changePageHandle () { // 翻頁后觸發方法 this.formatPages(); this.showPagesMore(); this.onModelChange(this.currentPage); // 觸發ngModel綁定的數據更新 this.changePage.emit(this.currentPage); // 向外觸發自定義方法,並傳值 } onModelChange: Function = () => { }; // 頁面的值改變,調用改方法,並調用onModelChange傳入改變后的值,實現值得回傳 writeValue(val): void { // 頁面初始化時時,調用該方法,傳入初始值 if (val) { this.currentPage = val; } } registerOnChange(fn: any): void { // 頁面值改變時,調用該方法,傳入新值實現回傳 this.onModelChange = fn; } registerOnTouched(fn: any): void { } }
<!--custom-pagination.html-->
<ul class="custom-pagination"> <li class="page-item first-page" *ngIf="fastTurnBtn" [ngClass]="{'disabled': currentPage === 1}" (click)="goToPage(1)"><span><<</span></li> <li class="page-item prev-page" *ngIf="turnBtn" [ngClass]="{'disabled': currentPage === 1}" (click)="prevNextPage('上一頁')"><span><</span></li> <li class="page-item left-more-page" *ngIf="showLeftMoreStatus && moreBtn" (click)="leftMoreClick()" title="查看更多"><span></span></li> <li class="page-item" *ngFor="let item of showPageList" [ngClass]="{'active': currentPage === item}" (click)="goToPage(item)">{{item}}</li> <li class="page-item right-more-page" *ngIf="showRightMoreStatus && moreBtn" (click)="rightMoreClick()" title="查看更多"><span></span></li> <li class="page-item next-page" *ngIf="turnBtn" [ngClass]="{'disabled': currentPage === totalPage}" (click)="prevNextPage('下一頁')"><span>></span></li> <li class="page-item last-page" *ngIf="fastTurnBtn" [ngClass]="{'disabled': currentPage === totalPage}" (click)="goToPage(totalPage)"><span>>></span></li> </ul>
// custom-pagination.css
.custom-pagination{ overflow: hidden; margin: 10px 0; text-align: center; } .page-item{ display: inline-block; width: 25px; height: 25px; line-height: 23px; border: 1px solid #06a0e7; color: #06a0e7; text-align: center; border-radius: 3px; margin: 0 2px; cursor: pointer; user-select: none; vertical-align: middle; } .prev-page,.next-page{ width: auto; padding: 0 2px; } .page-item.active{ border-color: #06a0e7; background: #06a0e7; color: #fff; } .disabled{ cursor: not-allowed; border-color: #d9d9d9; color: #00000040; } .prev-page span,.next-page span,.first-page span,.last-page span{ display: inline-block; transform: scale(.5, 1.2) translateY(-1px); min-width: 20px; } .left-more-page span,.right-more-page span{ position: relative; display: inline-block; width: 100%; height: 100%; } .left-more-page span:after,.right-more-page span:after{ position: absolute; content: '•••'; width: 100%; height: 100%; left: 0; top: 0; font-size: 12px; } .left-more-page:hover span:after{ content: '<<'; transform: scale(.5, 1.2); } .right-more-page:hover span:after{ content: '>>'; transform: scale(.5, 1.2); }
以上方案可實現簡單的分頁器組件,有可以更好的實現方案或者優化實現的,希望指出。
