實現基於Vue的Pagination分頁器組件

今天來實現一個基礎的 Pagination 分頁器組件~html

需求

  • 可以根據外部傳入的total(數據總數),以每頁10條數據變化頁面總數。
  • 頁數pages小於8時,顯示所有頁碼。
  • 頁數pages大於7時,自動調整顯示的頁碼,其他頁碼省略代替。
  • 頁數pages大於7時,頁碼顯示規則爲顯示當前頁(current)+-2個頁碼以及第一頁和最後一頁頁碼。

演示

不知道爲啥錄屏的時候不能錄入鼠標的狀態= =,不然會顯示紅色圓圈禁用和手指覆蓋的圖標= =vue

實現

對於html元素,須要【上一頁】【頁碼】【下一頁】三個部分。分別用button,ul,button實現。bash

  • 【上一頁】須要添加禁用屬性preDisable;前往上一頁的點擊事件goPre;
  • 【頁碼】須要判斷是否展現頁碼button仍是省略號…;
  • 【下一頁】須要添加禁用屬性nextDisable;前往下一頁的點擊事件goNext;

對於組件,咱們須要用到Vue的props,data,computed,watch,created,methods這些屬性或鉤子。markdown

  • 【props】接收參數數據總數total。
  • 【data】定義當前頁current,每頁顯示數據pageSize,頁碼列表pages,頁碼長度pageLength。
  • 【computed】用於計算是否禁用上一頁preDisable或下一頁按鈕nextDisable。
  • 【watch】監聽數據總數total的改變在計算頁碼列表getPagesLength();監聽當前頁current改變,向父組件傳遞參數當前頁。
  • 【created】初始化計算頁碼列表getPagesLength()。
  • 【methods】計算頁碼列表getPagesLength();點擊頁碼jumpToPage (index);上一頁goPre ();下一頁goNext ();頁碼是否被省略isShowBtn (index);是否顯示省略號isShowEllipsis (index)。

基礎組件pagination.vue

<template>
  <div class="pagination-wrapper">
    <button :disabled="preDisable" @click="goPre">&#60;</button> <!--上一頁按鈕-->
    <ul>                                                         <!--頁碼列表-->
      <li v-for="index in pages" :key="index"  ref="pages">
        <button @click="jumpToPage(index)" v-if="isShowBtn(index)" :class="current===index?'active':''">{{index}}</button>
        <div v-else-if="isShowEllipsis (index)" class="ellipsis">&#8230;</div> <!--省略號-->
      </li>
    </ul>
    <button :disabled="nextDisable" @click="goNext">&#62;</button> <!--上一頁按鈕-->
  </div>
</template>

<script type='text/ecmascript-6'>
export default {
  props: {
    total: {
      type: Number,
      default: 200
    }
  },
  data () {
    return {
      current: 1, // 定義當前頁current
      pageSize: 10, // 每頁顯示數據pageSize
      pages: [], // 頁碼列表pages
      pageLength: 0 // 頁碼長度pageLength
    }
  },
  computed: {
    preDisable () { // 是否禁用上一頁
      return this.current === 1
    },
    nextDisable () { // 是否禁用下一頁
      return this.current === this.pageLength
    }
  },
  watch: {
    total (val) { // 監聽數據總數total的改變在計算頁碼列表getPagesLength()
      this.getPagesLength()
    },
    current (val) { // 監聽當前頁current改變,向父組件傳遞參數當前頁
      this.$emit('change', val)
    }
  },
  created () { // 初始化計算頁碼列表getPagesLength()
    this.getPagesLength()
  },
  methods: {
    getPagesLength () { // 計算頁碼列表
      const more = this.total % this.pageSize ? 1 : 0
      this.pageLength = this.total / this.pageSize + more
      this.pages = new Array(this.pageLength)
      for (let i = 0; i < this.pageLength; i++) {
        this.pages[i] = i + 1
      }
    },
    jumpToPage (index) { // 點擊頁碼
      this.current = index
    },
    goPre () { // 上一頁
      this.current -= this.current === 1 ? 0 : 1
    },
    goNext () { // 下一頁
      this.current += this.current === this.pageLength ? 0 : 1
    },
    isShowBtn (index) { // 頁碼是否被省略
      if (this.pageLength < 8) {
        return true
      } else {
        if (index === 1 || index === this.pageLength) {
          return true
        } else {
          if (this.current < 4 && index < 6) {
            return true
          } else if (this.current > this.pageLength - 4 && index > this.pageLength - 6) {
            return true
          } else if (index < this.current + 3 && index > this.current - 3) {
            return true
          } else {
            return false
          }
        }
      }
    },
    isShowEllipsis (index) { // 是否顯示省略號
      return index === 2 || index === this.pageLength - 1
    }
  }
}
</script>

<style lang="stylus" scoped>
.pagination-wrapper
	width 100%
	margin 10px
	display flex
	ul
		display flex
		.active
			border solid 1px #1296db
		.ellipsis
			font-weight bold
			color #999
			line-height 24px
	button
		height 30px
		width 30px
		margin 0 5px
		border-radius 3px
		border solid 1px #ccc
		color #777
		font-weight bold
		background #fff
		overflow hidden
		user-select none
		&:hover
			border solid 1px #1296db
			cursor pointer
		&:disabled
			border solid 1px #ccc
			color #ccc
			cursor not-allowed
</style>

複製代碼

應用組件pagination-apply.vue

<template>
	<div>
		<Pagination :total="total" @change="changePagination"></Pagination>
		<div class="desc">當前頁: {{current}}</div>
	</div>
</template>

<script type='text/ecmascript-6'>
import Pagination from 'base/pagination'
export default {
  data () {
    return {
      total: 200, // 必傳傳遞參數total
      current: 1
    }
  },
  methods: {
    changePagination (current) {
      this.current = current
    }
  },
  components: {
    Pagination
  }
}
</script>
複製代碼

優化

  • 咱們能夠設置鼠標覆蓋時顯示手指圖標cursor pointer,禁用時顯示紅色圓圈斜線表示禁用cursor not-allowed。
  • 使用user-select none來禁止用戶選中按鈕中的文字,優化體驗。

更多推薦

相關文章
相關標籤/搜索