手把手教你寫一個react分頁組件


分頁是web項目中hin常見的功能;今天就來做一個基於react框架的分頁插件;

首先,思路是父級組件通過props傳入數據總數,每頁顯示條數,顯示多少按鈕,當前頁發生變化時的處理函數等配置;其次,組件本身維護一個數組,數組中記錄當前應該顯示的頁數序列,用戶觸發跳頁操作時更新這個數組並調用父組件傳入的處理函數;

先看一下要完成的效果:

分頁效果 

嘛~就是這么簡單。下面開始。。

一、定義props類型和默認props

static propTypes = {
    pageSize: PropTypes.number, /* 每頁顯示多少行 */
    currentPage: PropTypes.number, /* 默認選中頁 */
    dataCount: PropTypes.number,  /* 數據總條數 */
    maxSize: PropTypes.number,  /* 最多顯示按鈕數 */
    forbidJump: PropTypes.bool, /* 是否隱藏跳頁操作相關按鈕 */
    hidePreAndNext: PropTypes.bool, /* 是否隱藏上一頁下一頁按鈕 */
    previousLabel: PropTypes.string,  /* 上一頁按鈕顯示文字 */
    nextLabel: PropTypes.string,  /* 下一頁顯示文字 */
    onChange: PropTypes.func   /* 觸發跳頁操作時調用的處理函數 */
  }
  static defaultProps = {
    pageSize: 10,
    currentPage: 1,
    dataCount: 0,
    forbidJump: false,
    hidePreAndNext: false,
    maxSize: 5,
    previousLabel: '<',
    nextLabel: '>',
    onChange: null
  }

二、創建state,維護組件狀態(_getBtnIndexList方法返回頁數按鈕序列數組,因為constructor和componentWillReceiveProps中都要用到,故封裝成一個方法)

constructor(props) {
    super(props)
    let _indexList = this._getBtnIndexList()
    this.state = {
      currentPage: props.currentPage,
      btnIndexList: [],   /* 維護要顯示的頁碼序列 */
      pagesCount: 0,    /* 總頁數 */
      targetPage:null      /* 跳轉操作臨時存儲輸入值*/
    }
  }

 三、_getBtnIndexList方法實現

_getBtnIndexList = (newProps) => {
    let _props = newProps || this.props
    let _pagesCount = Math.ceil(_props.dataCount / _props.pageSize), _maxSize = _props.maxSize, _btnInsexlist = []
    if (_pagesCount <= _maxSize + 1) {
      for (let i = 1; i <= _pagesCount; i++) {
        _btnInsexlist.push(i)
      }
      return {
        btnInsexlist: _btnInsexlist,
        pagesCount: _pagesCount
      }
    }
    for (let i = 1; i <= _maxSize - 1; i++) {
      _btnInsexlist.push(i)
    }
    _btnInsexlist.push('...')
    _btnInsexlist.push(_pagesCount)
    return {
      btnInsexlist: _btnInsexlist,
      pagesCount: _pagesCount
    }
  }

四、將this.state.btnIndexList數組map到render方法中

let _btns = []
    for (let i = 0; i < this.state.btnIndexList.length; i++) {
      if (typeof this.state.btnIndexList[i] === 'number') {
        _btns.push(
          <li className={this.state.currentPage === this.state.btnIndexList[i] ? 'active' : ''} key={`page${i}`} onClick={() => { this._handleJumpPage(this.state.btnIndexList[i]) }}>
            <a href="javascript:;">{this.state.btnIndexList[i]}</a>
          </li>
        )
      } else {
        _btns.push(
          <li key={`page${i}`}>
            <span>{this.state.btnIndexList[i]}</span>
          </li>
        )
      }
    }

  。。。。。。此處省略132個字

<ul>
          {
            /**
             * 是否隱藏上頁下頁操作按鈕
             */
            this.props.hidePreAndNext ? null : (
              <li
                className={this.state.currentPage === 1 ? 'disabled' : ''}
                onClick={() => {
                  this._goPrePage()
                }}
              >
                <a href="javascript:;">{this.props.previousLabel || '<'}</a>
              </li>
            )
          }

          {_btns}
          {
            /**
             * 是否隱藏上頁下頁操作按鈕
             */
            this.props.hidePreAndNext ? null : (
              <li
                className={this.state.currentPage === this.state.pagesCount ? 'disabled' : ''}
                onClick={() => {
                  this._goNextPage()
                }}
              >
                <a href="javascript:;">{this.props.nextLabel || '>'}</a>
              </li>
            )
          }

          {
            /**
             * 是否隱藏跳頁操作按鈕
             */
            this.props.forbidJump ? null : (
              <li className="dis">
                共{this.state.btnIndexList[this.state.btnIndexList.length - 1]}頁,到第<input
                  type="tel"
                  value={this.state.targetPage}
                  onChange={(e) => {
                    this.setState({
                      targetPage: /^\d+$/.test(e.target.value) ? e.target.value - 0 : ''
                    })
                  }}
                /><div style={{ lineHeight: '31px', paddingRight: '15px', display: 'inline' }}>頁</div>
              </li>
            )
          }

          {
            this.props.forbidJump ? null : (
              <li className="dis">
                <a
                  href="javascript:;"
                  onClick={() => {
                    if (!/^\d+$/.test(this.state.targetPage)) {
                      return
                    }
                    this.state.targetPage > this.state.pagesCount ? this._handleJumpPage(this.state.pagesCount) : this._handleJumpPage(this.state.targetPage)
                    this.setState({
                      targetPage: ''
                    })
                  }}
                >確定</a>
              </li>
            )
          }
        </ul>

 五、跳頁分頁處理(改變按鈕序列號數組)

_handleJumpPage = (pageIndex) => {
    if (pageIndex === this.state.currentPage) {
      return
    }
    this.setState({ currentPage: pageIndex })
    if (this.state.pagesCount <= this.props.maxSize) {
      return
    }
    if (pageIndex < (this.props.maxSize - 1)) {
      let _indexList = this._getBtnIndexList()
      this.setState({
        btnIndexList: _indexList.btnInsexlist
      })
      return
    }
    if (pageIndex > this.state.pagesCount - (this.props.maxSize - 2)) {
      let _btns = [1, '...']
      for (let i = (this.state.pagesCount - (this.props.maxSize - 2)); i <= this.state.pagesCount; i++) {
        _btns.push(i)
      }
      this.setState({
        btnIndexList: _btns
      })
      return
    }
    if (pageIndex > (this.props.maxSize - 2)) {
      let _pre = Math.ceil((this.props.maxSize - 3) / 2)
      let _btns = [1, '...']
      for (let i = _pre; i > 0; i--) {
        _btns.push(pageIndex - i)
      }
      _btns.push(pageIndex)

      if ((this.state.pagesCount - pageIndex) <= (this.props.maxSize - 3)) {
        for (let i = pageIndex + 1; i <= this.state.pagesCount; i++) {
          _btns.push(i)
        }
      } else {
        for (let i = 1; i <= _pre; i++) {
          _btns.push(pageIndex + i)
        }
        _btns.push('...')
        _btns.push(this.state.pagesCount)
      }

      this.setState({
        btnIndexList: _btns
      })
    }
  }

ok,大概就是這樣,有空再調整吧、、、


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM