CviLux_fe/src/components/customUI/Pagination.vue

195 lines
5.1 KiB
Vue

<script setup>
import { defineProps, ref, computed, inject, watch } from "vue";
import { twMerge } from "tailwind-merge";
import { data } from "autoprefixer";
import { useI18n } from "vue-i18n";
const { t } = useI18n();
/* -------------------------------------------------------------
> 6 頁 => 會有 input 跳頁,且前三後三顯示
---------------------------------------------------------------- */
const props = defineProps({
pageSize: {
type: Number,
default: 10,
}, // 幾頁為一組
totalPages: {
type: Number,
default: 0,
},
onPageChange: Function, // 用來接收目前返回的頁數
dataSource: Array,
totalItems: Number,
sort: Object,
});
const current_table_data = inject("current_table_data");
const currentPage = ref(0);
const totalPage = ref(0);
const beforeInputPage = computed(() => {
if (totalPage.value > 6) {
return 3;
} else {
return totalPage.value;
}
});
const choosePage = (page) => {
currentPage.value = parseInt(page);
props.onPageChange
? props.onPageChange(parseInt(page))
: changePageData(parseInt(page));
};
// 數據一次性傳送
const changePageData = (currentPage) => {
const start = (currentPage - 1) * props.pageSize;
const end = currentPage * props.pageSize;
const data = props.dataSource.slice(start, end);
current_table_data.updateDataSource(data);
};
watch(
() => [props.dataSource, props.sort],
([newVal, newVal2]) => {
// console.log(props.dataSource, newVal);
currentPage.value = 1;
totalPage.value =
props.totalPages || Math.ceil(props.dataSource.length / props.pageSize);
props.onPageChange
? current_table_data.updateDataSource(props.dataSource)
: changePageData(1);
},
{
deep: true,
}
);
const pageInput = computed(() => {
if (currentPage.value > 3 && currentPage.value < totalPage.value - 2) {
return currentPage.value;
} else {
return "";
}
});
</script>
<template>
<div
class="relative flex justify-end items-end my-5"
v-if="dataSource.length > 0"
>
<span class="mx-1">
<button
type="button"
class="prev focus:border-0 disabled:text-gray-500 hover:text-warning"
:disabled="currentPage === 1"
@click="
() => {
choosePage(currentPage - 1 > 0 ? currentPage - 1 : 1);
}
"
>
<font-awesome-icon :icon="['fas', 'chevron-left']" class="text-3xl" />
</button>
</span>
<ul class="flex items-center list-none">
<li
v-for="page in beforeInputPage"
:key="`page${page}`"
:class="
twMerge(
'w-10 h-10 mx-1 border-2 border-sub-success rounded-full flex items-center justify-center',
currentPage === page ? 'bg-sub-success' : 'bg-transparent'
)
"
@click="
() => {
choosePage(page);
}
"
>
<span class="text-white font-extrabold italic">
{{ page }}
</span>
</li>
</ul>
<span
v-if="totalPage < 6"
class="absolute -bottom-8 -translate-x-1/2 text-base text-center"
>
{{ dataSource.length }} {{ $t("table.in_otal") }}</span
>
<label
v-if="totalPage > 6"
class="mx-2 relative input border-2 border-sub-success flex items-center gap-2"
>
<input
type="text"
maxlength="6"
class="bg-transparent h-full w-20 font-extrabold italic text-lg"
:placeholder="t('table.skip_to')"
:value="pageInput"
@change="
(e) => {
choosePage(e.target.value);
}
"
/>
<span
><font-awesome-icon
:icon="['fas', 'search']"
class="text-xl text-sub-success"
/></span>
<span
class="w-full text-center absolute -bottom-8 left-1/2 -translate-x-1/2 text-base"
>
{{ totalItems || dataSource.length }} {{ $t("table.in_otal") }}</span
>
</label>
<ul
v-if="totalPage > 6"
class="flex flex-row-reverse items-center list-none"
>
<li
v-for="(page, index) in 3"
:key="`page${totalPage - index}`"
:class="
twMerge(
'w-10 h-10 mx-1 border-2 border-sub-success rounded-full flex items-center justify-center',
currentPage === totalPage - index
? 'bg-sub-success'
: 'bg-transparent'
)
"
@click.stop.prevent="
() => {
choosePage(totalPage - index);
}
"
>
<span class="text-white font-extrabold italic">
{{ totalPage - index }}
</span>
</li>
</ul>
<span class="mx-1">
<button
type="button"
class="next focus:border-0 disabled:text-gray-500 hover:text-warning"
:disabled="currentPage === totalPage"
@click="
() => {
choosePage(
currentPage + 1 <= totalPage ? currentPage + 1 : totalPage
);
}
"
>
<font-awesome-icon :icon="['fas', 'chevron-right']" class="text-3xl" />
</button>
</span>
</div>
</template>