react 寫 分頁插件

react 寫 分頁插件

其實分頁插件不管在什麼項目咱們都會用到,如今的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;
        }
    }
}
}複製代碼
相關文章
相關標籤/搜索