193 lines
5.0 KiB
Vue
193 lines
5.0 KiB
Vue
<script setup>
|
|
import { defineProps, ref, computed, inject, watch } from "vue";
|
|
import { twMerge } from "tailwind-merge";
|
|
import { data } from "autoprefixer";
|
|
/* -------------------------------------------------------------
|
|
> 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 cursor-pointer',
|
|
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 }} 筆</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="跳至"
|
|
: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 }} 筆</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>
|