效果图:

image.png

初始结构:

  1. <template>
  2. <div class="xtx-pagination">
  3. <a href="javascript:;" class="disabled">上一页</a>
  4. <span>...</span>
  5. <a href="javascript:;" class="active">3</a>
  6. <a href="javascript:;">4</a>
  7. <a href="javascript:;">5</a>
  8. <a href="javascript:;">6</a>
  9. <a href="javascript:;">7</a>
  10. <span>...</span>
  11. <a href="javascript:;">下一页</a>
  12. </div>
  13. </template>
  14. <script>
  15. export default {
  16. name: 'XtxPagination'
  17. }
  18. </script>
  19. <style scoped lang="less">
  20. .xtx-pagination {
  21. display: flex;
  22. justify-content: center;
  23. padding: 30px;
  24. > a {
  25. display: inline-block;
  26. padding: 5px 10px;
  27. border: 1px solid #e4e4e4;
  28. border-radius: 4px;
  29. margin-right: 10px;
  30. &:hover {
  31. color: @xtxColor;
  32. }
  33. &.active {
  34. background: @xtxColor;
  35. color: #fff;
  36. border-color: @xtxColor;
  37. }
  38. &.disabled {
  39. cursor: not-allowed;
  40. opacity: 0.4;
  41. &:hover {
  42. color: #333
  43. }
  44. }
  45. }
  46. > span {
  47. margin-right: 10px;
  48. }
  49. }
  50. </style>

落地代码:

  1. <template>
  2. <div class="xtx-pagination">
  3. <a href="javascript:;" v-if="myCurrentPage===1" class="disabled">上一页</a>
  4. <a href="javascript:;" v-else @click="go(-1)">上一页</a>
  5. <!-- 如果起点按钮大于2就显示 -->
  6. <span v-if="pageInfo.start>2">...</span>
  7. <a href="javascript:;" @click="changePage(item)" :class="{active: myCurrentPage === item}" v-for="(item,idx) in pageInfo.pager" :key="idx"> {{item}} </a>
  8. <!-- 如果当前终点按钮小于总页数就显示 当终点按钮是20总按钮也是20 就不显示 -->
  9. <span v-if="pageInfo.end < pageInfo.pageCount">...</span>
  10. <!-- 如果当前按钮等于最后一页就禁止点击 disabled -->
  11. <a href="javascript:;" v-if="myCurrentPage==pageInfo.end" class="disabled">下一页</a>
  12. <a href="javascript:;" v-else @click="go(1)">下一页</a>
  13. </div>
  14. </template>
  15. <script>
  16. import { computed, ref, watch } from 'vue'
  17. export default {
  18. name: 'XtxPagination',
  19. props: {
  20. total: { type: Number, default: 100 },
  21. pageSize: { type: Number, default: 10 },
  22. currentPage: { type: Number, default: 1 },
  23. btnCount: { type: Number, default: 5 }
  24. },
  25. setup (props, { emit }) {
  26. const myTotal = ref(100) // 总条数
  27. const myPageSize = ref(5) // 每页共几条
  28. const myCurrentPage = ref(3) // 用户实时点击,修改
  29. const myBtnCount = ref(5) // 分页按钮的个数5个
  30. // 让当前的页码处于正中间
  31. // const pager = ref([1, 2, 3, 4, 5])
  32. // 根据上边信息,实时计算 pager,起始页码,结束页码
  33. const pageInfo = computed(() => {
  34. // 总页数 = 总条数/每页几条
  35. const pageCount = Math.ceil(myTotal.value / myPageSize.value)
  36. // 起点 = 当前页数-总页数/2 举例 3 - Math.floor(5/2) = 1
  37. let start = myCurrentPage.value - Math.floor((myBtnCount.value / 2))
  38. // 终点 = 起点页数 + 总页数 - 1 距离 1 + 5 -1 || 3 + 5 -1
  39. let end = start + myBtnCount.value - 1
  40. // 意外1 当起点小于1
  41. if (start < 1) {
  42. start = 1
  43. // 终点= 当前页数>总页数?总页数 否则 当前页数
  44. end = myBtnCount.value > pageCount ? pageCount : myBtnCount.value
  45. }
  46. // 意外2 当终点大于最大页码
  47. if (end > pageCount) {
  48. end = pageCount
  49. // 起点= 终点+(-所有页数+1)>1?1:= 终点+(-所有页数+1)
  50. start = (end - myBtnCount.value + 1) < 1 ? 1 : (end - myBtnCount.value + 1)
  51. }
  52. const pager = []
  53. for (let i = start; i <= end; i++) {
  54. pager.push(i)
  55. }
  56. return { start, end, pageCount, pager }
  57. })
  58. // 上一页下一页
  59. const go = (step) => {
  60. myCurrentPage.value += step
  61. }
  62. const changePage = (page) => {
  63. // 如果等于现在页页码 保持不动
  64. if (page === myCurrentPage.value) return
  65. myCurrentPage.value = page
  66. emit('currentCahnge', page)
  67. }
  68. // 监听传入的值改变
  69. watch(props, () => {
  70. myTotal.value = props.total
  71. myPageSize.value = props.pageSize
  72. myCurrentPage.value = props.currentPage
  73. myBtnCount.value = props.btnCount
  74. }, { immediate: true })
  75. return { myTotal, myPageSize, myCurrentPage, myBtnCount, pageInfo, go, changePage }
  76. }
  77. }
  78. </script>
  79. <style scoped lang="less">
  80. .xtx-pagination {
  81. display: flex;
  82. justify-content: center;
  83. padding: 30px;
  84. > a {
  85. display: inline-block;
  86. padding: 5px 10px;
  87. border: 1px solid #e4e4e4;
  88. border-radius: 4px;
  89. margin-right: 10px;
  90. &:hover {
  91. color: @xtxColor;
  92. }
  93. &.active {
  94. background: @xtxColor;
  95. color: #fff;
  96. border-color: @xtxColor;
  97. }
  98. &.disabled {
  99. cursor: not-allowed;
  100. opacity: 0.4;
  101. &:hover {
  102. color: #333
  103. }
  104. }
  105. }
  106. > span {
  107. margin-right: 10px;
  108. }
  109. }
  110. </style>