今日目標:
在 src/components 中新增一個 Pagination.vue
<template>
<div class="pagination-container">
<div class="pagination-info">
顯示第 {{ startItem }}-{{ endItem }} 項,共 {{ totalItems }} 項結果
</div>
<div class="pagination-controls">
<button
class="pagination-btn prev-btn"
:disabled="currentPage === 1"
@click="$emit('page-change', currentPage - 1)"
>
← 上一頁
</button>
<div class="page-numbers">
<button
v-for="page in visiblePages"
:key="page"
class="page-btn"
:class="{ active: page === currentPage }"
@click="$emit('page-change', page)"
>
{{ page }}
</button>
</div>
<button
class="pagination-btn next-btn"
:disabled="currentPage === totalPages"
@click="$emit('page-change', currentPage + 1)"
>
下一頁 →
</button>
</div>
</div>
</template>
<script setup>
import { computed } from 'vue'
const props = defineProps({
currentPage: { type: Number, required: true },
totalPages: { type: Number, required: true },
totalItems: { type: Number, required: true },
itemsPerPage: { type: Number, default: 10 }
})
const emit = defineEmits(['page-change'])
const startItem = computed(() => {
return (props.currentPage - 1) * props.itemsPerPage + 1
})
const endItem = computed(() => {
return Math.min(props.currentPage * props.itemsPerPage, props.totalItems)
})
const visiblePages = computed(() => {
const pages = []
const maxVisible = 5
let start = Math.max(1, props.currentPage - Math.floor(maxVisible / 2))
let end = Math.min(props.totalPages, start + maxVisible - 1)
if (end - start + 1 < maxVisible) {
start = Math.max(1, end - maxVisible + 1)
}
for (let i = start; i <= end; i++) {
pages.push(i)
}
return pages
})
</script>
<script setup>
import Pagination from './components/Pagination.vue'
...
const currentPage = ref(1)
const itemsPerPage = 10
function handlePageChange(page) {
currentPage.value = page
// Scroll to top when page changes
window.scrollTo({ top: 0, behavior: 'smooth' })
}
const totalPages = computed(() => {
return Math.ceil(filteredPosts.value.length / itemsPerPage)
})
const paginatedPosts = computed(() => {
const start = (currentPage.value - 1) * itemsPerPage
const end = start + itemsPerPage
return filteredPosts.value.slice(start, end)
})
...
</script>
<template>
<Header />
<main>
...
<div v-if="filteredPosts.length > 0">
<div class="table-container">
<PostTable :posts="paginatedPosts" @select="openDetail"/>
</div>
<Pagination
v-if="totalPages > 1"
:current-page="currentPage"
:total-pages="totalPages"
:total-items="filteredPosts.length"
:items-per-page="itemsPerPage"
@page-change="handlePageChange"
/>
</div>
...
</main>
</template>
因為 code 比較長,就只貼了關於這個主題有更動的部分
最後,附上昨天美化的網頁XDD
底下是按下後會呈現的詳細資訊