无限滚动和v-for

时间:2019-03-23 14:33:21

标签: vue.js

我最近才刚开始使用Vue,到目前为止效果很好,但是遇到了一个问题,我无法找到一个好的解决方案。

我有一个包含几个不同部分的照相馆。我有一个总体的图库组件,一个图库部分和一个图像组件。本质上,我为每个部分使用一个照片数组来存储该部分的照片数据。在我使用v-for的部分中显示照片。图库会无限滚动,因此当您滚动到底部时,会加载更多图像,并且该部分的照片阵列会更新。

这是我的问题,当前,照片阵列存储在整个图库组件的数据上,因此,当我更新其中一个照片阵列时,似乎会导致整个画廊重新渲染。屏幕上的图像越多,对性能的影响越差,页面的响应性越差。 我知道我可以将照片数组移到各个部分的数据,但据我所知,仍然可以重新渲染整个部分。

我真的不知道是否有什么好的解决方案可以完成我想做的事情,具有一定的反应性,但只能更新发生变化的事情。我不知道这样的事情是否可行。 我尝试弄乱计算的数据,属性,方法等,但是找不到更好的解决方案。

这是我在整个图库组件中使用的代码:

    <template>
    <div class="photo-gallery">

        <gallery-section v-for="(section, index) in sections" v-bind:section="section" class="photo-gallery__section" v-bind:key="index"></gallery-section>

    </div>
</template>

<script>
    import * as qb from "../queryBuilder";
    let layout = [
        {
            title: "Highlighted Photos",
            request: {
                filters: qb.group([
                    qb.filter("rating", ">=", 4),
                ]),
                options: {
                    offset: 0,
                    limit: 2,
                    order: ["rand()"],
                    size: 740
                }
            },
            total: 2,
            photoClass: "photo--highlighted",
            loading: false,
            photos: []
        },
        {
            title: "More photos",
            request: {
                filters: qb.group([
                    qb.filter("rating", ">=", 2),
                ]),
                options: {
                    offset: 0,
                    limit: 40,
                    order: ["rand()"]
                }
            },
            total: Infinity,
            loading: false,
            photos: []
        }
    ];
    export default {
        data() {
            return {
                sections: layout,
                currentSection: 0
            }
        },
        mounted() {
            this.getPhotos(this.sections[0]);
            this.getPhotos(this.sections[1]);
        },
        methods: {
            getPhotos(section) {
                section.loading = true;
                let currentSection = this.currentSection;

                fetch(`api/photos/search/filter/${JSON.stringify(section.request.filters)}/${JSON.stringify(section.request.options)}`)
                .then(response => response.json())
                .then(response => {
                    section.photos.push(...response.images);
                    // Set offset for next request
                    this.sections[this.currentSection].request.options.offset = section.photos.length;
                    // Check if current section is complete or if less than the requested amount of photos was returned
                    if (
                        this.sections[this.currentSection].total === section.photos.length ||
                        response.images.length < this.sections[this.currentSection].request.options.limit
                    ) {
                        if (this.sections.length -1 != this.currentSection) {
                            // Move onto next section
                            this.currentSection++;
                        } else {
                            // Set currentSection to null if all sections have been fully loaded
                            this.currentSection = null;
                        }
                    }
                })
                .finally(() => {
                    section.loading = false;
                });
            },
            scrollHandler() {
                if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight - 500) {
                    if (this.currentSection != null && !this.sections[this.currentSection].loading) {
                        this.getPhotos(this.sections[this.currentSection]);
                    }
                }
            }
        },
        created() {
            window.addEventListener("scroll", this.scrollHandler);
        },
        destroyed() {
            window.removeEventListener("scroll", this.scrollHandler);
        }
}
</script>

我还注意到的一件事是,每当加载更多照片时,页面上每个照片组件的安装功能都会运行。

有人能指出我正确的方向吗?任何建议将不胜感激。

谢谢你,杰森。

1 个答案:

答案 0 :(得分:0)

问题是我为照片组件实例生成密钥的方式,在上面包含的代码中看不到。我发现生成的随机数作为密钥意味着Vue无法跟踪元素,因为密钥会不断变化。我现在在服务器端生成唯一密钥,并改为使用它们。现在可以正常工作了。