【问题标题】:How to use "Vue-infinite-loading" in nuxt without loading data by axios?如何在nuxt中使用“Vue-infinite-loading”而不通过axios加载数据?
【发布时间】:2021-11-03 09:51:17
【问题描述】:

我正在开发 Nuxt 应用程序。对于我的一个动态页面,我想用 无限滚动 显示数据。为此,我决定使用Vue-infinite-loading。我阅读了this article 并浏览了 Vue-infinite-loading 的文档。在他们两个中,他们都使用 axios 模块逐步加载数据以在滚动到达该页面中的特定点时显示在页面中。但是在我的页面中,在$strapi module 和 Nuxt fetch 钩子的帮助下,数据已经根据 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 hook 中获取数据(根据页面 id 不同),然后将其放入 listBooks Vue 数据中。我想要做的是首先在 listBooks 中显示例如 2 数据,当滚动到达第二个数据(此处为第二张卡片)的末尾时,我显示使用无限滚动方法逐步其余数据。所以我使用了一个名为 listShowComputed data 并在 v-for 中使用它。然后我把我认为可能在 infiniteScroll 方法中工作的代码。但显然这不起作用,因为我只是猜测。如果有人知道如何更改该代码以使其工作并以无限滚动的方式显示数据,请帮助我解决此问题。

【问题讨论】:

  • 不需要[ this.listBooks[0], this.listBooks[1] ],保留一个数组并根据您的滚动在其中添加新值。喜欢10 items + (10 items * amount of times you reached the infinite loader bottom border)

标签: vue.js nuxt.js vue-infinite-loading


【解决方案1】:

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

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

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

我的previous answer 可能有助于进一步了解它。

PS:当心一些reactivity issues,你在处理数组时可能有一天会遇到。

【讨论】:

  • 我不明白你提到的“@infinite event”的含义。你的意思是我必须用其他东西替换模板部分 infinite-loading 组件中的@infinite="infiniteScroll" 吗?另外我想知道我的代码必须是异步才能完美运行吗?
  • @hamid-davodi no, @infinite="infiniteScroll" 完全没问题。我只是在强调你应该关注听众的什么,但在这里一切都很好,是的。如果您需要,您的代码可能是异步的。例如,如果您想使用axios,是的,它需要是异步的。如果您不想/不需要,并且只是已经从 Strapi 获取了包含整个数据的数据,则无需在其之上进行异步。通常,前端是很多异步的!
【解决方案2】:

我终于在kissu的回答和the article mentioned in my question代码的启发下找到了解决方案。这里我将贴出我整个 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 个数据时显示它们并滚动页面。

【讨论】:

    猜你喜欢
    • 2017-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-27
    • 2021-12-23
    • 2019-08-13
    • 1970-01-01
    • 2019-06-21
    相关资源
    最近更新 更多