Pagination.vue 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. <template>
  2. <div class="flex justify-center items-center space-x-4 bg-white shadow-md py-4 px-6 rounded-lg">
  3. <button
  4. @click="onPageChange(currentPage - 1)"
  5. :disabled="currentPage === 1"
  6. class="px-4 py-2 bg-primary text-white rounded-md hover:bg-primary-dark disabled:opacity-50 disabled:cursor-not-allowed transition-colors duration-300 focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2"
  7. >
  8. 上一页
  9. </button>
  10. <span class="px-4 py-2 bg-gray-100 text-primary font-semibold rounded-md">
  11. {{ currentPage }} / {{ totalPages }}
  12. </span>
  13. <button
  14. @click="onPageChange(currentPage + 1)"
  15. :disabled="currentPage === totalPages"
  16. class="px-4 py-2 bg-primary text-white rounded-md hover:bg-primary-dark disabled:opacity-50 disabled:cursor-not-allowed transition-colors duration-300 focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2"
  17. >
  18. 下一页
  19. </button>
  20. </div>
  21. </template>
  22. <script setup>
  23. import { defineProps, defineEmits, computed } from 'vue';
  24. const props = defineProps({
  25. currentPage: {
  26. type: Number,
  27. required: true
  28. },
  29. totalItems: {
  30. type: Number,
  31. required: true,
  32. default: 1
  33. },
  34. itemsPerPage: {
  35. type: Number,
  36. required: true
  37. }
  38. });
  39. const emit = defineEmits(['page-change']);
  40. const totalPages = computed(() => {
  41. const totalItems = props.totalItems || 0;
  42. const itemsPerPage = props.itemsPerPage || 1; // 避免除以零
  43. return Math.ceil(totalItems / itemsPerPage);
  44. });
  45. const onPageChange = (page) => {
  46. if (page >= 1 && page <= totalPages.value) {
  47. emit('page-change', page);
  48. }
  49. };
  50. </script>