其實分頁插件不管在什麼項目咱們都會用到,如今的ui框架也自帶這個插件,但我最近正在學習react,實在不知寫什麼。就用分頁插件練一下手,若是有錯誤的請指出,謝謝。react
先總結一下思路吧,可能寫博客,在寫插件之間都應該總結一些思路吧。其實最難算的應該就是分頁條數大於10的時候吧,有的用點代替,有的用輪播方式來代替,這裏我使用點的方式來代替bash
公式: Math.ceil( total / pageSize ) 總條數除以一頁多少條 獲得總共多少頁(這裏使用的下取整,不管還餘多少條,確定會有新的一頁。)
框架
分頁效果less
參數函數
/**
* 分頁插件
* @param total // 總條數
* @param page // 當前頁
* @param pageSize // 一頁多少條
* @param fastPage // 是否有上一頁 或者 下一頁
* @param onPageChange // 回調函數 頁數改變時觸發
* @param onPageSize // 回調函數,一頁多少條時改變
* **/
複製代碼
所有代碼學習
import React from 'react';
import './pagination.less';
/**
* 分頁插件
* @param total // 總條數
* @param page // 當前頁
* @param pageSize // 一頁多少條
* @param fastPage // 是否有上一頁 或者 下一頁
* @param onPageChange // 回調函數 頁數改變時觸發
* @param onPageSize // 回調函數,一頁多少條時改變
* **/
class Pagination extends React.Component{
constructor(props){
super(props);
let params = {
total: 0, // 總條數
page: 1, // 當前頁
pageSize: 10, // 一頁多少條
pageSizeArray:[
{
title: '10/頁',
key: 10,
},
{
title: '20/頁',
key: 20,
},
{
title: '30/頁',
key: 30,
},
{
title: '40/頁',
key: 40,
},
{
title: '50/頁',
key: 50,
},
],
totalArray: [],
activeIndex: 1,
fastPage: true, // 是否 上一頁 和 下一頁
defaultNum: 5,
pageNum: 0, //總共多少頁
jumpValue:'',
}
this.state = Object.assign(params,this.props);
this.nextHandle = this.nextHandle.bind(this);
this.prevHandle = this.prevHandle.bind(this);
this.pageInit = this.pageInit.bind(this);
this.init = this.init.bind(this);
this.jumpLeave = this.jumpLeave.bind(this);
this.jumpChange = this.jumpChange.bind(this);
this.pageSizeHandle = this.pageSizeHandle.bind(this);
}
init(){ // 初始化整個函數
let pageNum = Math.ceil( this.state.total / this.state.pageSize );
return new Promise((resolve, reject) => {
this.setState({pageNum: pageNum},()=>{
resolve()
})
})
}
jumpLeave(e){
let _this = this;
if(e.keyCode == 13) {
if(this.state.jumpValue) {
let num = Number(this.state.jumpValue)
this.setState({activeIndex:num},()=>{
_this.pageInit();
})
}
}
}
pageInit(){
let pageNum = this.state.pageNum;
console.log(pageNum, 44444)
let totalArr = [];
/**
* 默認展現 5 條
* 1 ... 45678...10
* **/
let intervalNumber = this.state.defaultNum;
if(pageNum >= intervalNumber) {
let arr = [],arr1 = [],arr2 = [];
arr.push(1);
if(this.state.activeIndex > intervalNumber && this.state.activeIndex < pageNum - intervalNumber){ // 取中間部分
arr1.push('...');
arr1.push( this.state.activeIndex - 2 )
arr1.push( this.state.activeIndex - 1 )
arr1.push( this.state.activeIndex )
arr1.push( this.state.activeIndex + 1 )
arr1.push( this.state.activeIndex + 2 )
arr1.push('...');
} else if( this.state.activeIndex <= intervalNumber ) { // 取開頭部分
for( let i =1; i< pageNum; i++ ) {
if(i == intervalNumber || i+1 == pageNum) {
break;
}
arr1.push(i+1);
}
if(pageNum > intervalNumber){
arr1.push('...')
}
} else if( this.state.activeIndex >= pageNum - intervalNumber ) { // 取末尾部分
arr1.push('...');
for( let i = pageNum - intervalNumber; i< pageNum; i++ ) {
if(i == pageNum) {
break;
}
arr1.push(i);
}
}
arr2.push(pageNum);
totalArr = totalArr.concat(arr,arr1,arr2)
} else {
for(let i=0; i<pageNum; i++) {
totalArr.push(i+1)
}
}
this.setState({totalArray:totalArr});
}
componentWillUpdate( prevState,state ){
// console.log(prevState,state, 9999)
}
componentWillMount(){ // 至關於mouted
this.init().then(() => {
this.pageInit()
});
}
componentWillReceiveProps(props){ // props 改變時 觸發的函數
setTimeout(()=>{
this.state = Object.assign(this.state,this.props);
this.init().then(() => {
this.pageInit()
});
},0)
}
nextHandle(){
let _this = this;
if( this.state.activeIndex < this.state.pageNum ) {
let index = this.state.activeIndex + 1;
this.setState({activeIndex:index}, ()=>{
_this.props.onPageChang(index);
_this.pageInit();
})
}
}
prevHandle(){
let _this = this;
if( this.state.activeIndex > 1 ) {
let index = this.state.activeIndex - 1;
this.setState({activeIndex:index}, ()=>{
_this.props.onPageChang(index);
_this.pageInit();
})
}
}
jumpChange(e){
let val = e.target.value;
this.setState({'jumpValue':val});
}
itemClick(item,index){
let _this = this;
let num = this.state.activeIndex;
if( item == '...' && index > 2 ){
num += 5;
} else if(item == '...' && index < 5 ){
num -= 5;
}else{
num = item;
}
this.setState({activeIndex:num},()=>{
_this.pageInit()
_this.props.onPageChang(num);
})
}
pageSizeHandle(e){
let val = e.target.value;
let _this = this;
this.setState({pageSize:val},()=> {
_this.init().then(() => {
_this.pageInit()
});
_this.props.onPageSize(val);
})
}
render(){
const totalHtml = this.state.totalArray.map((item,index) => {
let activeClass= item == this.state.activeIndex ? 'text-active' : '';
return (
<span onClick={this.itemClick.bind(this,item,index)} key={index} className={`${activeClass}`}>
{item}
</span>
)
})
const pageSizeHtml = this.state.pageSizeArray.map((item, index) => {
return (
<option key={index} value={item.key}>{item.title}</option>
)
})
const nextPage = this.state.fastPage ? (<button disabled={this.state.activeIndex == this.state.pageNum} onClick={this.nextHandle} className={'next-page'}>下一頁</button>) : '';
const prevPage = this.state.fastPage ? (<button disabled={this.state.activeIndex == 1} onClick={this.prevHandle} className={'prev-page'}>上一頁</button>) : '';
return (
<div id={'pagination'}>
<div className={'page-content'}>
{prevPage}
<div className={'text-content'}>
{totalHtml}
</div>
{nextPage}
<div className="pageSize">
<select defaultValue={this.state.pageSize} onChange={this.pageSizeHandle}>
{pageSizeHtml}
</select>
</div>
<div className="jump">
<span>跳至</span>
<input value={this.jumpValue} onChange={this.jumpChange} onKeyUp={this.jumpLeave} />
<span>頁</span>
</div>
<div className={'text-total'}>
總計:{this.state.total} 條
</div>
</div>
</div>
)
}
}
export default Pagination;複製代碼
樣式代碼flex
#pagination{
.page-content {
display:flex;
.text-content {
span{
display:inline-block;
width: 28px;
line-height: 28px;
text-align: center;
.page();
border: 1px solid #ddd;
background-color:#efefef;
margin: 10px 6px;
color: #666;
}
.text-active{
.activePage();
}
}
.page(){
height: 28px;
border-radius: 4px;
&:hover{
cursor:pointer;
}
}
.activePage(){
border: 1px solid #1890ff;
background-color:#1890ff;
color: #fff;
}
.prev-page, .next-page{
.page();
.activePage();
margin: 10px 20px;
}
button[disabled], .next-page[disabled]{
border: 1px solid #ddd;
background-color:#efefef;
color: #999;
&:hover{
cursor:not-allowed;
}
}
.text-total{
height: 28px;
margin: 10px 20px;
line-height: 28px;
}
.jump{
margin: 10px 6px;
input{
width: 40px;
height: 28px;
border:1px solid #ddd;
border-radius: 4px;
margin: 0 6px;
padding: 0 6px;
&focus{
border:1px solid #1890ff;
}
}
}
.pageSize{
margin: 14px 6px;
select{
width: 100px;
}
}
}
}複製代碼