Edited at

b-tableとb-paginationでページネーションを実装する上でハマった点とその対応方法

bootstrap-vueを使った時にb-tableでページングを実現する方法がわからず、ちょっとハマったので自分用のメモとして投稿しました。

APIから取得したデータをb-tableで表示し、b-paginationを使ってページングするUIを作りたくて下記のように実装しました。1ページ目は問題なかったのですが、2ページ目以降は何も表示されず...。

<template>

<b-table
:items="items"
:current-page="currentPage"
:per-page="perPage"
:fields="fields"
responsive="sm"
/>
<nav>
<b-pagination
v-model="currentPage"
:total-rows="totalRows"
:per-page="perPage"
prev-text="Prev"
next-text="Next"
hide-goto-end-buttons
/>
</nav>
</template>
<script>
data: () => {
return {
fields: [],
items: [],
currentPage: 1,
perPage : 10,
totalRows : 0,
}
},
methods: {
async fetch() {
const res = await api.fetch()
this.perPage = res.data.perPage
this.totalRows = res.data.totalRows
this.items = res.data.items
}
}
</script>

this.itemsにAPIから取得した要素を追加していかないとそりゃ次のページは表示されないんですが、アホな僕はひたすら b-table refresh doen't work とか調べてたので、全く答えにたどり着けませんでした。

スマートな回答がわからず、結局下記のような感じでページングを実現しました。

<script>

data: () => {
return {
fields: [],
items: [],
currentPage: 1,
perPage : 10,
totalRows : 0,
}
},
methods: {
async fetch() {
const res = await api.fetch({
currentPage: this.currentPage,
perPage: this.perPage,
})
this.perPage = res.data.perPage
this.totalRows = res.data.totalRows
this.items = new Array((this.currentPage - 1) * this.perPage).fill({})
this.items = this.items.concat(res.data.items).map(function (item) {
// 取得したitemを加工?
return item
})
}
},
watch: {
currentPage(newValue, oldValue) {
this.fetch()
},
},
</script>

一回指定されたページまでのダミーを作って、APIから取得したデータを追加するという... :innocent:

APIで一旦全レコードを取得して、this.itemsにぶっこんでしまうのが早いんでしょうか?

とにかく絶対他にいい&かっこいい方法があるはず...