Bootstrap 如何在Vue中实现两个可滚动列的分页或无限滚动

ghg1uchk  于 2023-05-27  发布在  Bootstrap
关注(0)|答案(1)|浏览(243)

我需要一个关于无限滚动分页的快速提示。我有两个引导列,它们将使用ul元素创建从数据库加载的滚动列表。我想实现一个带有无限滚动的延迟加载,以避免electron vue应用程序出现性能问题。我在一个vue方法中编写了这个伪代码,但我不确定如何分割我拥有的两个数组,并使用v-if循环

paginateDatasets( col ) {
            //
            if( !this.store.supplierFound || !this.store.clientFound ){
                switch( col ) {
                    case 'suppliers':
                        //console.dir( this.$refs.listedSupplier )
                        //scroll top per 50 referenze = 3651.199951171875 px
                        //console.dir( this.$refs.listColSuppliers.scrollTop )
                        //console.dir( this.$refs.listColSuppliers.scrollHeight )
                        let diff = this.$refs.listColSuppliers.scrollHeight - Number(this.$refs.listColSuppliers.scrollTop) 
                        //
                        let clientHeight = this.$refs.listColSuppliers.clientHeight
                        
                        console.log( Number(diff) )
                        if( Number( diff ) === 555 ){
                            //this.
                            console.log('Last index')
                            console.dir( this.$refs.listedSupplier.dataset.index )
                            console.log('Loading more results')
                        }
                        break;
                    case 'clients':
                        console.dir( this.$refs.listedClient )       
                        
                        break;
                }
            }
        }

一个数组将容纳近2000个对象,第二个将容纳58000个对象。我的想法是检查滚动条何时到达具有74vh的固定高度的列的末尾,而应用程序的整个容器,独立于应用程序窗口大小将具有100vh的固定高度。任何提示或帮助将不胜感激。谢谢大家。

mwkjh3gx

mwkjh3gx1#

可以参考以下代码:

<script>
export default {
    name: "VirtualList",
    props: {
        // An array for traversing
        listData: {
            type: Array,
            default: () => [],
            require: true,
        },
        // The height of each of these terms
        itemHeight: {
            type: Number,
            default: 20,
            require: true,
        },
    },
    computed: {
        // The total height of the list
        listHeight() {
            return this.listData.length * this.itemHeight;
        },
        //Number of visible
        visibleCount() {
            return Math.ceil(this.screenHeight / this.itemHeight);
        },
        // offset
        getTransform() {
            return `translate3d(0,${this.startOffset}px,0)`;
        },
        // The actual rendered dom
        visibleData() {
            return this.listData.slice(
                    this.start,
                    Math.min(this.end, this.listData.length)
            );
        },
    },
    mounted() {
        this.screenHeight = this.$el.clientHeight;
        this.start = 0;
        this.end = this.start + this.visibleCount;
    },
    data() {
        return {
            // Visible area height
            screenHeight: 0,
            // offset
            startOffset: 0,
            // Index of the first item in the visual area
            start: 0,
            // The index of the last item in the viewable area
            end: null,
        };
    },
    methods: {
        scrollEvent() {
            // Gets the current scrollTop
            let scrollTop = this.$refs.list.scrollTop;
            // Computed index
            this.start = Math.floor(scrollTop / this.itemHeight);
            // Computed index
            this.end = this.start + this.visibleCount;
            // Computed offset
            this.startOffset = scrollTop - (scrollTop % this.itemHeight);
        },
    },
};
</script>
<style scoped>
.infinite-list-container {
    height: 100%;
    overflow: auto;
    position: relative;
    -webkit-overflow-scrolling: touch;
}

.infinite-list-phantom {
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    z-index: -1;
}

.infinite-list {
    left: 0;
    right: 0;
    top: 0;
    position: absolute;
    text-align: center;
}
</style>
<template>
    <div ref="list" class="infinite-list-container" @scroll="scrollEvent($event)">
        <div
                class="infinite-list-phantom"
                :style="{ height: listHeight + 'px' }"
        ></div>
        <div class="infinite-list" :style="{ transform: getTransform }">
            <slot v-for="data in visibleData" :data="data"/>
        </div>
    </div>
</template>

此代码实现了一个虚拟列表组件,该组件具有以下功能和实现原理:
1.产品特点:

  • 它基于提供的列表数据(listData)和项目高度(itemHeight)在有限的可见区域内显示大量数据。
  • 它通过只渲染视口中可见的项目来实现虚拟滚动技术,而不是一次渲染所有项目,以提高性能并减少内存消耗。

1.实施原则:

  • 在模板部分,容器元素 Package 列表内容,并使用ref属性引用它。
  • 使用两个子元素来实现滚动容器效果:
  • . infinite-list-phantom:占位符元素,高度等于整个列表,确保容器的正确滚动范围。
  • . infinite-list:包含可见的数据项,滚动效果是通过应用CSS transform属性和使用getTransform计算的偏移量来实现的。
  • 槽用于呈现可见数据项。
  • 计算属性用于动态计算列表的总高度(listHeight)、可见列表项的数量(visibleCount)、偏移量的样式(getTransform)和实际可见列表数据(visibleData)。
  • 在组件的mounted钩子中,获取容器元素的可见高度,初始化开始索引(start)和结束索引(end)。
  • 监听滚动事件(@scroll),并根据计算出的滚动位置(scrollTop)和项目高度(itemHeight),更新起始索引、结束索引和偏移量,以更新显示的数据并调整滚动期间的位置。

通过上述实现,该代码可以通过仅渲染当前可见的项来高效地渲染大量数据,从而实现高性能的虚拟滚动列表效果。

相关问题