Pagination.vue 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. <template>
  2. <!-- 分页组件 -->
  3. <div class="pagination">
  4. <!-- 上一页按钮 -->
  5. <a
  6. :class="[
  7. 'page-button',
  8. currentPage > 1 ? 'enable' : ''
  9. ]"
  10. :href="ssrUrl + '?page=' + (currentPage - 1)"
  11. @click.prevent="goToPage(currentPage - 1)"
  12. >
  13. &lt;
  14. </a>
  15. <!-- 页码按钮 -->
  16. <a
  17. v-for="page in visiblePages"
  18. :key="page"
  19. class="page-button enable"
  20. :class="{ active: page === currentPage }"
  21. :href="ssrUrl + '?page=' + page"
  22. @click.prevent="goToPage(page)"
  23. >
  24. {{ page }}
  25. </a>
  26. <!-- 下一页按钮 -->
  27. <a
  28. :class="[
  29. 'page-button',
  30. currentPage < totalPages ? 'enable' : ''
  31. ]"
  32. :href="ssrUrl + '?page=' + (currentPage + 1)"
  33. @click.prevent="goToPage(currentPage + 1)"
  34. >
  35. &gt;
  36. </a>
  37. </div>
  38. </template>
  39. <script setup lang="ts">
  40. import { ref, computed, watch } from "vue";
  41. const props = defineProps({
  42. ssrUrl: {
  43. type: String,
  44. default: '',
  45. },
  46. /**
  47. * 当前页码
  48. */
  49. currentPage: {
  50. type: Number,
  51. required: true,
  52. },
  53. /**
  54. * 总页数
  55. */
  56. totalPages: {
  57. type: Number,
  58. required: true,
  59. },
  60. });
  61. const emit = defineEmits(["update:currentPage"]);
  62. // 计算显示的页码范围
  63. const visiblePages = computed(() => {
  64. const pages = [];
  65. const maxPagesToShow = 10; // 最多显示 10 个页码
  66. const halfMax = Math.floor(maxPagesToShow / 2);
  67. // 计算起始页码
  68. let startPage = Math.max(1, props.currentPage - halfMax);
  69. let endPage = startPage + maxPagesToShow - 1;
  70. // 如果超出总页数,调整起始页码
  71. if (endPage > props.totalPages) {
  72. endPage = props.totalPages;
  73. startPage = Math.max(1, endPage - maxPagesToShow + 1);
  74. }
  75. for (let i = startPage; i <= endPage; i++) {
  76. pages.push(i);
  77. }
  78. return pages;
  79. });
  80. // 跳转到指定页码
  81. const goToPage = (page: number) => {
  82. if (page >= 1 && page <= props.totalPages) {
  83. emit("update:currentPage", page);
  84. }
  85. };
  86. </script>
  87. <style lang="scss" scoped>
  88. @use "@/assets/scss/colors" as *;
  89. .pagination {
  90. display: flex;
  91. justify-content: center;
  92. gap: 10px;
  93. margin-top: 20px;
  94. }
  95. .page-button {
  96. width: 40px;
  97. height: 40px;
  98. display: flex;
  99. align-items: center;
  100. justify-content: center;
  101. background-color: $box-inset-color;
  102. color: $text-color;
  103. cursor: pointer;
  104. opacity: 0.4;
  105. &:hover {
  106. background-color: $box-hover-color;
  107. }
  108. &.enable {
  109. opacity: 1;
  110. }
  111. }
  112. .page-button.active {
  113. background-color: $primary-color;
  114. color: $text-color-light;
  115. }
  116. </style>