vue3版のを使おうと思ったが ts の書き方わからんので
vue2で利用していたときのをそのまま使う。
追記
no-more や no-results時にテキストを表示させたくない場合は
<infinite-loading @infinite="infiniteHandler" :identifier="inf.infiniteId">
<template #no-more><span></span></template>
<template #no-results><span></span></template>
</infinite-loading>
とする。
インスコ
npm install vue-infinite-loading@3.0.0-alpha.0-0
以下を参考にすりゃブラウザバックしたときも同じ位置に戻る。
hoge.vue
<template>
<div>
<div>
<router-link v-for="(v,key) in inf.list" :key="key" :to="{ path: '/article/'+v.id+'/'}">
<h3>{{v.name}}</h3>
</router-link>
</div>
<infinite-loading @infinite="infiniteHandler" :identifier="inf.infiniteId">
<template #no-more>
すべて読み込みました
</template>
<template #no-results>
すべて読み込みました
</template>
</infinite-loading>
</div>
</template>
<script>
import InfiniteLoading from 'vue-infinite-loading';
import {Infmix} from "./Infmix";
export default {
mixins: [Infmix],
components: {
InfiniteLoading,
},
data(){
return {
inf: {
url:'/articles/show/',
query: {
page:1,
},
storageName:"artice-show",//要変更
list: [],
}
}
},
created(){
},
methods: {
setQuery(){
this.inf.infiniteId++;//リセットするために必要
//古いのを一旦リセット
this.inf.list = [];
this.inf.query.page = 1;
this.clearStorage();
this.$router.replace({
path: "/"+this.inf.storageName+"/"
});
},
},
}
</script>
infmix.js
import InfiniteLoading from 'vue-infinite-loading';
export const Infmix = {
components: {
InfiniteLoading,
},
mounted() {
//ページ数が指定されている場合はブラウザのバックされたとき
if(this.$route.query.page){
this.readPageStorage()
if(window.pageYOffset != sessionStorage.getItem('y')){
scrollTo(0, sessionStorage.getItem('y'));
}
} else {
//他の画面を経由して来た場合は検索結果をリセット
console.log("他のページを経由してきたので検索結果をリセットします");
this.clearStorage()
}
},
//ページを離れたときに現在の y 座標を 保存
beforeRouteLeave(to, from, next) {
try {
sessionStorage.setItem('y',this.$root.scroll.Y);
next();
} catch(e) {
return false;
}
},
beforeMount(){
if(this.$route.query){
//繰り返し
for (var key in this.$route.query) {
if(key != 'page'){
this.inf.query[key] = this.$route.query[key];
}
}
}
},
methods: {
// infinite-loadingが表示された際の処理
async infiniteHandler($state) {
axios.post(this.inf.url,this.inf.query).then(e => {
if(e.data.res.data.length) {
this.inf.list = this.inf.list.concat(e.data.res.data);
this.inf.query.page++;
this.$router.replace({
path: "/"+this.inf.storageName+"/",
query:this.inf.query,
}, () => {}, () => {});
this.addPageStorage();
$state.loaded();
} else {
console.log("全ての読み込みが完了しました");
$state.complete();
}
}).catch((error) => {
$state.error();
});
},
// //現在のページ情報を保存する
addPageStorage() {
sessionStorage.setItem(this.inf.storageName + '_list',JSON.stringify(this.inf.list));
sessionStorage.setItem(this.inf.storageName + '_query',JSON.stringify(this.inf.query));
},
// //戻ってきた場合、ページ情報を復元する
readPageStorage() {
//ブラウザから直接 ページ数を指定されてきた場合は該当ページを表示させる
if (sessionStorage.getItem(this.inf.storageName + '_list') === null) {
this.inf.query.page = this.$route.query.page;
} else {
//時間経過してブラウザを開いた場合は session storage が切れる。
//その歳はバグるので sessionstorageを全て削除
try {
this.inf.list = JSON.parse(sessionStorage.getItem(this.inf.storageName + '_list'));
this.inf.query = JSON.parse(sessionStorage.getItem(this.inf.storageName + '_query'));
} catch(e) {
// 戻り値は任意
this.clearStorage();
return false;
}
}
},
//
// //session storage を 削除。 clear sessionStorage.clear() は使わない。
clearStorage() {
sessionStorage.removeItem(this.inf.storageName + '_list');
sessionStorage.removeItem(this.inf.storageName + '_query');
},
},
}