Vuetify/v-data-tableで無眼スクロールを実装する際に困ったことのメモと実装例
v-data-tableに指定しないとスタイル補正される
- disable-pagination
- hide-default-footer
tableのDOMで無限scrollする場合
- スクロールバーを出すため、heightを指定する!
- DOMをscriptで取得するためのrefかidを付ける!
<v-data-table
ref="tables"
:headers="headers"
:items="desserts"
:loading="isLoaging"
disable-pagination
hide-default-footer
fixed-header
height="500"
class="elevation-1"
></v-data-table>
無限ローディングの実装例
実装に必要なdataを用意する!
data.headersはVuetifyのサンプルから引用
data() {
return {
isLoaging: false,
headers: [
{
text: "Dessert (100g serving)",
align: "start",
sortable: false,
value: "name",
},
{ text: "Calories", value: "calories" },
{ text: "Fat (g)", value: "fat" },
{ text: "Carbs (g)", value: "carbs" },
{ text: "Protein (g)", value: "protein" },
{ text: "Iron (%)", value: "iron" },
],
desserts: []
};
}
Vueのライフサイクルフックでスクロールを検知する!
- tableで無限scrollする場合、DOMを指定してスクロールを検知する!
- windowのスクロール幅で無限scrollする場合、window.scrollY などを使う!
mounted() {
const instance = this.$refs.tables.$el.childNodes[0];
instance.addEventListener("scroll", this.onScroll);
}
最下部までスクロールされた際の処理を追記する!
- スクロール幅などの条件を付けて、さらに読み込み処理を書く。
- ローディングアニメーションの為、用意したフラグを利用する!
今回はローカルで用意したものを追加、アニメーションの為にsetTimeOutしています
methods: {
onScroll() {
const instance = this.$refs.tables.$el.childNodes[0];
if (
instance.scrollTop + instance.clientHeight >= instance.scrollHeight &&
!this.isLoaging
) {
this.isLoaging = true;
const add = () => {
// 読み込んだ差分を追加
const toAddDessert = [
{
name: "Frozen Yogurt",
calories: 159,
fat: 6.0,
carbs: 24,
protein: 4.0,
iron: "1%",
},
...
];
const mergedItems = [...this.desserts, ...toAddDessert];
this.desserts = mergedItems;
this.isLoaging = false;
};
setTimeout(add, 700);
}
}
}
#注意点
- eventListnerを適切に解除する!
- DOM関連でのエラーハンドリングをする!
- v-data-tableのkeyについても考える! keyについてはこちらが参考になるでしょう。
あとがき
Vuetifyを利用することで簡単に実装できました!
windowのスクロール幅を利用したものはまた追記するかもです!