1

我正在开发 Nuxt 应用程序。对于我的一个动态页面,我想显示无限滚动的数据。为此,我决定使用Vue-infinite-loading。我阅读了这篇文章,还浏览了Vue-infinite-loading的文档。在他们两个中,他们都使用axios模块逐步加载数据,以在滚动到达该页面中的特定点时显示在页面中。但是在我的页面中,在$strapi模块和 Nuxt提取钩子的帮助下,数据已经根据 page-id 存在于页面中。我的页面的整个代码如下:

<template>
    <v-container fluid>
        <v-row>
            <v-col cols="10" class="mx-auto">
                <p v-if="$fetchState.pending">
                    در حال بارگذاری اطلاعات
                </p>
                <p v-else-if="$fetchState.error">
                    مشکلی در نمایش اطلاعات به وجود آمده است.
                </p>
                <div v-else>
                    <h1 v-html="this.fourType[this.nameRoute]['title']">
                    </h1>
                    <section>
                        <BaseCard 
                        v-for="item in listShow"
                        :key="item.id"
                        :imgId = "item.id" 
                        :sizeCard = "270"
                        >
                            <template v-slot:tozih>
                                {{ item.tozih }}
                            </template> 

                            <template v-slot:aout>
                                {{ item.author }}
                            </template>  
                        </BaseCard>
                    </section>
                    
                    <infinite-loading 
                    spinner="spiral"
                    @infinite="infiniteScroll"
                    >
                    </infinite-loading>
                    
                </div>
            </v-col>
        </v-row>
    </v-container>
</template>

<script>
export default {
    data() {
        return {
            listBooks: [],
            fourType:{
                short: {
                    title: "در این قسمت می&zwnj;توانید کتابها را به ترتیب از کوچک (کمترین تعداد صفحه) به بزرگ (بیشترین تعداد صفحه) مشاهده نمایید:",
                    request: 1
                },
                programming: {
                    title: "در این قسمت می&zwnj;توانید کتب مرتبط با برنامه&zwnj;نویسی (دارای برچسب برنامه&zwnj;نویسی) را به ترتیب به روزرسانی (از جدیدترین به قدیمی&zwnj;ترین) مشاهده نمایید:",
                    request: 2
                },
                new: {
                    title: "در این قسمت می&zwnj;توانید کتب موجود در سایت را به ترتیب به روز رسانی (از جدید به قدیم) مشاهده نمایید:",
                    request: 3
                },
                random: {
                    title: "در این قسمت می&zwnj;توانید به صورت تصادفی به مشاهده تمامی کتب موجود در سایت بپردازید:",
                    request: 4
                }
            },
            nameRoute: this.$route.params.type
        }
    }, // end of data

    computed: {
        listShow: function() {
            return [ this.listBooks[0], this.listBooks[1] ]
        }
    }, // end of computed

    methods: {
        infiniteScroll($state) {
             
                    if (this.listBooks.length > 1) {
                        this.listBooks.forEach((item) => this.listShow.push(item))
                        $state.loaded()  
                    } 
                    else {   
                        $state.complete()  
                    } 
                    
        }
    }, // end of methods

    async fetch() {
        switch (this.nameRoute) {
            case "short":
                this.listBooks = await this.$strapi.$books.find("_sort=pageQuantity:ASC");
                break;
            case "programming":
                this.listBooks = await this.$strapi.$books.find({ 'tags.name': ['برنامه نویسی'], _sort: 'updated_at:DESC' });
                break;
            case "new":
                this.listBooks = await this.$strapi.$books.find("_sort=updated_at:DESC");
                break;
            default:
                this.listBooks = this.$store.getters["books/randomBook"](this.$store.state.books.list2.length);
                break;
        }
        
    }
}
</script>

<style scoped>

</style>

在代码中,我在 fetch 挂钩中获取数据(根据页面 id 不同),然后将其放入listBooks Vue 数据中。我想要做的是首先在listBooks中显示例如2 个数据,当滚动到达第二个数据(此处为第二张卡)的末尾时,我使用无限滚动方法逐步显示其余数据。所以我使用了一个名为listShow的计算数据并在 v-for 中使用它。然后我把我认为也许它可能在infiniteScroll方法中工作的代码。但显然这不起作用,因为我只是猜测。如果有人知道如何更改该代码以工作并在无限滚动中显示数据,请帮助我解决这个问题。

4

2 回答 2

2

通常,无限加载器用于存储一小部分数据,然后出于性能原因对其进行扩展:不必一次加载 100 个元素,而是加载 10 个,然后再加载 10 个等等......

如果您已经立即在本地拥有数据并且喜欢它的行为,而无需从您的 Strapi 后端进行任何“分页”,您可以随时关注@infinite事件并使用下一个元素增加初始元素数组的大小。

说如果您显示其中的 10 个,想要向下滚动并再显示 10 个:显示前 10 个,然后在infinite触发事件时,将另外 10 个项目附加到您的初始数组,依此类推。

之前的回答可能有助于更多地理解它。

PS:当心处理数组时可能会遇到的一些反应性问题。

于 2021-11-03T10:33:24.143 回答
1

我终于在Kissu answer 的帮助下,并在我的问题中提到的文章代码的启发下找到了解决方案。在这里,我将发布我的整个 Nuxt 页面的代码,以显示使用其他开发人员的答案:

<template>
    <v-container fluid>
        <v-row>
            <v-col cols="10" class="mx-auto">
                <p v-if="$fetchState.pending">
                    در حال بارگذاری اطلاعات
                </p>
                <p v-else-if="$fetchState.error">
                    مشکلی در نمایش اطلاعات به وجود آمده است.
                </p>
                <div v-else>
                    <h1 v-html="this.fourType[this.nameRoute]['title']">
                    </h1>
                    <section>
                        <BaseCard 
                        v-for="item in list2"
                        :key="item.id"
                        :imgId = "item.id" 
                        :sizeCard = "270"
                        >
                            <template v-slot:tozih>
                                {{ item.tozih }}
                            </template> 

                            <template v-slot:aout>
                                {{ item.author }}
                            </template>  
                        </BaseCard>
                    </section>
                    
                    <infinite-loading 
                    spinner="spiral"
                    @infinite="infiniteScroll"
                    >
                    </infinite-loading>
                    
                </div>
            </v-col>
        </v-row>
    </v-container>
</template>

<script>
export default {
    data() {
        return {
            listBooks: [],
            page: 0,
            list2: [],
            fourType:{
                short: {
                    title: "در این قسمت می&zwnj;توانید کتابها را به ترتیب از کوچک (کمترین تعداد صفحه) به بزرگ (بیشترین تعداد صفحه) مشاهده نمایید:",
                    request: 1
                },
                programming: {
                    title: "در این قسمت می&zwnj;توانید کتب مرتبط با برنامه&zwnj;نویسی (دارای برچسب برنامه&zwnj;نویسی) را به ترتیب به روزرسانی (از جدیدترین به قدیمی&zwnj;ترین) مشاهده نمایید:",
                    request: 2
                },
                new: {
                    title: "در این قسمت می&zwnj;توانید کتب موجود در سایت را به ترتیب به روز رسانی (از جدید به قدیم) مشاهده نمایید:",
                    request: 3
                },
                random: {
                    title: "در این قسمت می&zwnj;توانید به صورت تصادفی به مشاهده تمامی کتب موجود در سایت بپردازید:",
                    request: 4
                }
            },
            nameRoute: this.$route.params.type
        }
    }, // end of data

    methods: {
        infiniteScroll($state) {
        setTimeout(() => {    
            let emptyArr = [];
            for (let index = this.page*10; index < this.page*10+10; index++) {
                if (this.listBooks[index]) {
                    emptyArr.push(this.listBooks[index])
                }
            }
            
            if (emptyArr.length > 0) {
            emptyArr.forEach(
                (item) => this.list2.push(item)
            )
            $state.loaded();
            } else {
            $state.complete()
            }
            this.page++
        }, 500)            
                    
        }
    }, // end of methods

    async fetch() {
        switch (this.nameRoute) {
            case "short":
                this.listBooks = await this.$strapi.$books.find("_sort=pageQuantity:ASC");
                break;
            case "programming":
                this.listBooks = await this.$strapi.$books.find({ 'tags.name': ['برنامه نویسی'], _sort: 'updated_at:DESC' });
                break;
            case "new":
                this.listBooks = await this.$strapi.$books.find("_sort=updated_at:DESC");
                break;
            default:
                this.listBooks = this.$store.getters["books/randomBook"](this.$store.state.books.list2.length);
                break;
        }
        
    }
}
</script>

<style scoped>

</style>

两个重要的变化是:

1- 在我的 Vue 数据中使用一个名为list2的空数组,而不是 Vue计算数据

2-在我的infiniteScroll方法中使用一个名为emptyArr的变量,该方法仅保存例如10项原始数据(Vue listBooks 数据),并在每次从用户视图传递10 条数据时通过滚动页面显示它们。

于 2021-11-03T16:14:25.770 回答