vuetify3でテーブルを固定ヘッダーにしつつ無限スクロール機能をつけて実装しようとしたら少しハマったおはなし
今回やること
- テーブルを固定ヘッダーにしつつ、無限スクロール機能をつける
- vuetify3のDataTableとInfiniteScrollerを使って実装する
参考
data-table: https://vuetifyjs.com/en/components/data-tables/basics/
infinite-scroller: https://vuetifyjs.com/en/components/infinite-scroller/
これで行けると思ったがいけなかったコード
data-tableをinfinite-scrollで囲んで実装できるかなと思った
<v-infinite-scroll :items="items" height="400" @load="loadItems">
<v-data-table
:headers="headers"
:items="items"
:items-per-page="-1"
:fixed-header="true" // ヘッダーを固定するプロパティ
height="350"
>
<template #bottom /> <!-- ページネーションを削除している -->
</v-data-table>
</v-infinite-scroll>
〜〜〜〜〜 loadItem()は追加のitemsをロードする関数 〜〜〜〜〜〜〜
↓テーブルを固定ヘッダーにすることはできるが、無限スクロール機能が壊れてしまう。。
考えられる原因(予想)
- まず、DataTableでヘッダーを固定するにはfixed-header, heightプロパティを設定する必要があり、InfiniteScrollerもheightプロパティを設定する必要がある
- が、DataTableとInfiniteScrollerに設定したheightが競合してInfiniteScrollerのloadイベントがうまく検知できずにいるかもしれない
どうやって解決するか
- DataTableの中のbodyを消して、tbodyを自作してそこに無限スクロールの機能を持たせる感じにしてあげる
↓こんな感じ
<v-data-table
:headers="headers"
:items="items"
:items-per-page="-1"
:fixed-header="true"
height="350"
>
<template #body />
<template #tbody="{...slots}">
<v-infinite-scroll tag="tbody" :items="slots.internalItems" @load="loadItems" empty-text="">
<v-data-table-row
v-for="item in slots.internalItems"
:item="item"
:key="item.key"
:v-slots="slots"
/>
</v-infinite-scroll>
</template>
<template #bottom /> <!-- ページネーションを削除している -->
</v-data-table>
これで一旦テーブルのヘッダーを固定しつつ無限スクロールの機能を実装することができた
だがしかし、
どうしよ。
cssでゴリ押す
v-deepを使ってこのクルクルにcssを当てちゃいます
:deep(.v-infinite-scroll__side:last-child) {
position: relative;
top: 8px;
bottom: 8px;
display: table-row;
height: 56px;
}
:deep(.v-infinite-scroll__side > .v-progress-circular) {
position: absolute;
left: 50%;
transform: translateX(-50%);
}
いい感じに真ん中行きました!
最後はこんな感で固定ヘッダーにしつつ、無限スクロール機能を実装できました!
最後まで読んでくれてありがとうございます!! 誰かの参考になれば嬉しいです!