react 写 分页插件

react 写 分页插件

其实分页插件无论在什么项目我们都会用到,现在的ui框架也自带这个插件,但我最近正在学习react,实在不知写什么。就用分页插件练一下手,如果有错误的请指出,谢谢。

思路

先总结一下思路吧,可能写博客,在写插件之间都应该总结一些思路吧。其实最难算的应该就是分页条数大于10的时候吧,有的用点代替,有的用轮播方式来代替,这里我使用点的方式来代替

公式: Math.ceil( total / pageSize ) 总条数除以一页多少条 得到总共多少页(这里使用的下取整,无论还余多少条,肯定会有新的一页。

分页效果

参数

/**
 *  分页插件
 *  @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;复制代码


样式代码

#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;
        }
    }
}
}复制代码


转载于:https://juejin.im/post/5d0f24e2e51d4577523f23ac

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值