Vue3 pagination 頁數太多怎麼辦|無套件

Wendy Chang
Wendy Loops
Published in
6 min readMay 16, 2023

一直沒看到好用的套件,只好自己手刻一波了!!

我是參考這個codesandbox做的,但他沒辦法處理頁數過多的問題,但總之先理解他的寫法之後才比較好改。

html如下:
data是原始資料,paginatedData則是已經分好頁的資料

<template>
<div v-for="item in paginatedData" :key="item.index">{{ item.value }}</div>
<button @click="backPage">prev</button>
<button
v-for="item in Math.ceil(data.length / perPage)"
:key="item"
@click="() => goToPage(item)"
>
{{ item }}
</button>
<button @click="nextPage">next</button>
</template>

JS如下:

<script setup>
import { ref, computed } from "vue";

// 設定頁數 = 1
let page = ref(1);

// 原始資料(假的)
// 如果要匯入真資料就不用寫這句
const data = Array.from(Array(24).keys()).map((item) => {
return { index: item, value: `this_${item}` };
});

// 一頁要幾筆資料
const perPage = 10;

// 每10筆原始資料成為一個paginatedData(動態)
const paginatedData = computed(() =>
data.slice((page.value - 1) * perPage, page.value * perPage)
);

//下一頁
const nextPage = () => {
if (page.value !== Math.ceil(data.length / perPage)) {
page.value += 1;
}
};

// 上一頁
const backPage = () => {
if (page.value !== 1) {
page.value -= 1;
}
};

//前往某一頁
const goToPage = (numPage) => {
page.value = numPage;
};


</script>

paginatedData是依據page.value來決定是哪10筆資料,每按下下一頁/上一頁/去某頁,都能動態設定page.value,重新動態設定paginatedData,接著運用v-for渲染至頁面上,達到換頁效果。

頁數太多了怎辦

多到會超出頁面,對使用者也不友善。一直在想要怎麼處理這個問題,直到有一天我去逛momo購物,發現他們家的pagination只會呈現10頁:

於是我想到可以一次呈現10頁,但切換頁數時會往後找10頁。例如點擊第六頁,pagination會呈現6-15頁可供點擊。

設定pagination的起始(start)&最終(end):

const start = computed(()=>{

// 設定條件:如果page.value+10會小於總頁數,那就讓start = page.value
if(page.value + 10 <= Math.ceil(data.length / perPage)){
return page.value

// 如果會大於總頁數的話,那就讓start = 總頁數-9(從後面往前算10頁)
}else if(page.value+10 > Math.ceil(data.length / perPage) || page.value === Math.ceil(data.length / perPage)){
return Math.ceil(data.length / perPage)-9
}
})

// end同理
const end = computed(()=>{

if(page.value +10 <= Math.ceil(data.length / perPage)){
return page.value + 9

}else if(page.value+10 > Math.ceil(data.length / perPage) || page.value === Math.ceil(data.length / perPage)){
return Math.ceil(data.length / perPage)
}
})

設定v-show,從start渲染至end

<li
class="page-item"
v-for="(item,index) in Math.ceil(data.length / perPage)"
:key="index"
v-show="index >= start-1 && index < end"
@click="goToPage($event,item)"
>
<a class="page-link" :id="'page-'+item" href="#">{{ item }}</a>
</li>

這樣就完成嚕!

--

--

Wendy Chang
Wendy Loops

什麼都寫ㄉ前端工程師 / 影片剪輯師 / 自媒體經營者 斗內網址:https://p.ecpay.com.tw/E35E9DE