Skip to content

Instantly share code, notes, and snippets.

@Gkiokan
Created April 17, 2025 12:35
Show Gist options
  • Save Gkiokan/dac3e65eb2a17a654995a6933d779f85 to your computer and use it in GitHub Desktop.
Save Gkiokan/dac3e65eb2a17a654995a6933d779f85 to your computer and use it in GitHub Desktop.
AppPagination shadcn-vue
<template>
<div class="flex items-center gap-1">
<Button variant="outline" size="sm" :disabled="currentPage === 1" @click="setPage(1)">
«
</Button>
<Button variant="outline" size="sm" :disabled="currentPage === 1" @click="setPage(currentPage - 1)">
</Button>
<!-- Always show first page -->
<Button :variant="currentPage === 1 ? 'default' : 'outline'" size="sm" @click="setPage(1)">
1
</Button>
<!-- Show ellipsis if needed -->
<Button v-if="currentPage - 2 > 2" variant="outline" size="sm" disabled> ... </Button>
<!-- Dynamic middle pages -->
<template v-for="(page,p) in middlePages" :key="p">
<Button :variant="currentPage === page ? 'default' : 'outline'" size="sm" @click="setPage(page)">
{{ page }}
</Button>
</template>
<!-- Show ellipsis if needed -->
<Button v-if="currentPage + 2 < totalPages - 1" variant="outline" size="sm" disabled> ... </Button>
<!-- Always show last page if different from first -->
<Button v-if="totalPages > 1" :variant="currentPage === totalPages ? 'default' : 'outline'" size="sm" @click="setPage(totalPages)">
{{ totalPages }}
</Button>
<Button variant="outline" size="sm" :disabled="currentPage === totalPages" @click="setPage(currentPage + 1)">
</Button>
<Button variant="outline" size="sm" :disabled="currentPage === totalPages" @click="setPage(totalPages)">
»
</Button>
</div>
</template>
<script setup>
import { computed, ref, watch } from 'vue'
import { Button } from '@/components/ui/button'
const props = defineProps({
page: { type: Number, default: 1 },
per_page: { type: Number, default: 50 },
total: { type: Number, default: 100 },
sibblings: { type: Number, default: 3 },
})
const emit = defineEmits(['update:page'])
const currentPage = ref(props.page)
const totalPages = computed(() => Math.ceil(props.total / props.per_page))
const middlePages = computed(() => {
const pages = []
const start = Math.max(2, currentPage.value - props.sibblings)
const end = Math.min(totalPages.value - 1, currentPage.value + props.sibblings)
for (let i = start; i <= end; i++) {
pages.push(i)
}
return pages
})
const setPage = (page) => {
if (page < 1 || page > totalPages.value) return
currentPage.value = page
emit('update:page', page)
}
watch(() => props.page, (newPage) => {
currentPage.value = newPage
})
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment