2
1

More than 1 year has passed since last update.

vue-infinite-loading を 極める

Last updated at Posted at 2022-03-22

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');
        },


    },


}


2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1