封装一个vue2的虚拟列表

文章介绍了如何使用虚拟列表来优化大量数据渲染的性能问题。通过创建一个Vue组件,利用滚动事件动态计算并渲染可视区域内的DOM元素,减少实际渲染的DOM数量,提高应用性能。组件包含行高、显示条数、内容属性和数据传递方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

当我们需要很多条数据时,比如一万条时,如果只用v-for的话那么会渲染出一万个dom元素,这样是很消耗性能的,这时我们便可以使用虚拟列表了。


那什么是虚拟列表呢?
顾名思义,就是一个虚假的列表,可能它里面只渲染了20个dom元素,但是却可以通过滚动来展示一万条数据。
这里我封装了一个简单的虚拟列表的组件,里面包含了 rowHeight:行高、viewCount:显示条数、listItem:每一行显示的内容、listData:需要渲染的整体数据,另外还添加了一个点击向父组件传递信息的方法 onClick


组件如下,可直接复制

<template>
    <div class="viewPort" ref="viewPort" :style="{'--scroll-eight':rowHeight+'px'}" @scroll="handleScroll">
        <div class="scrollBar" ref="scrollBar"></div>
        <div class="list" ref="list">
            <div class="row" ref="row" v-for="(item,index) in finalList" :key="index" @click="handleClick(item)">
                {{ listItem?item[listItem]:item }}
            </div>
        </div>
    </div>
</template>

<script>
export default {
    data() {
        return {
            startIndex:0,  // 开始索引默认为0
            endIndex:this.viewCount, // 结束索引为列表展示条数
        };
    },
    props:{
        // 行高
        rowHeight:{
            type:Number,
            default:20,
        },
        // 显示条数
        viewCount:{
            type:Number,
            default:20,
        },
        // 显示内容
        listItem:{
            type:String,
            required:true
        },
        // 数据
        listData:{
            type:Array,
            required:true
        }
    },
    computed:{
        finalList(){
            return this.listData.slice(this.startIndex,this.endIndex); // 展示的数据
        }
    },
    mounted() {
        this.$refs.viewPort.style.height = this.$refs.list.style.height = this.rowHeight*this.viewCount + "px"; // 视口高度动态赋值
        this.$refs.scrollBar.style.height = (this.listData.length * this.rowHeight) + "px"; // 滚动条高度动态赋值
    },
    methods: {
        handleScroll(){
            this.startIndex = Math.round(this.$refs.viewPort.scrollTop/this.rowHeight); // 开始索引
            this.endIndex = this.startIndex + this.viewCount; // 结束索引
            this.$refs.list.style.transform = `translateY(${this.startIndex*this.rowHeight}px)`; // 向下平移
        },
        handleClick(e){
            this.$emit("onClick",e); // 绑定onClick事件,向调用者传递数据
        }
    },
};
</script>

<style scoped lang="scss">
.viewPort{
    width: 100%;
    overflow-y: auto;
    position: relative;
    background-color: #ff0;
    .list{
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        .row{
            height: var(--scroll-eight);
            width: 100%;
            &:hover{
                background-color: #eee;
                color: #f0f;
            }
            &:active{
                background-color: #eee;
                color: #f0f;
            }
        }
    }
}
</style>

使用方法如下:
在页面中引入这个组件

<template>
    <div>
        <v-list :list-item="title" :list-data="listData" @onClick="onClick" :view-count="10" :row-height="15"></v-list>
    </div>
</template>

<script>
import VList from './vList.vue'
export default {
    components:{VList},
    data() {
        let arrList = new Array(10000).fill(null).map((item,index)=>{return {title: index+1}});
        return {
            listData:'title',
            listData:Object.freeze(arrList)
        };
    },
    methods: {
        onClick(e){
            console.log(e,"<=========");
        }
    },
};
</script>

效果

虚拟列表效果

这样封装是比较便捷,但如果有大牛看到有需要修改的地方也欢迎留言呀

非常好的问题!VueJS一个流行的基于组件化的JavaScript框架,它使前端开发更加快速和简单。关于虚拟列表的组件,通常是通过虚拟化技术来展示大量的数据。这样做的目的是提高网页的性能和用户体验。虚拟化也可以让网页更加灵活,因为它可以在网页上动态添加和删除数据。下面是一个基于Vue JS实现的虚拟列表的组件的伪代码,你可以在它的基础上进行开发: ``` <template> <div class="virtual-list"> <div class="viewport" :style="{ height: viewportHeight + 'px' }" @scroll="onScroll"> <div :style="{ height: virtualHeight + 'px' }"></div> </div> </div> </template> <script> export default { name: 'VirtualList', props: { items: { type: Array, required: true }, itemHeight: { type: Number, required: true }, viewportHeight: { type: Number, default: 200 } }, data () { return { scrollTop: 0 } }, computed: { virtualHeight () { return this.items.length * this.itemHeight }, startIndex () { return Math.floor(this.scrollTop / this.itemHeight) }, endIndex () { return Math.min(this.startIndex + Math.ceil(this.viewportHeight / this.itemHeight), this.items.length) } }, methods: { onScroll (event) { this.scrollTop = event.target.scrollTop } } } </script> <style scoped> .viewport { overflow-y: auto; } </style> ``` 该代码定义了一个名为"VirtualList"的组件,它展示了一个具有虚拟化功能的列表。该组件接收一个名为"items"的数组,这是前端数据。虚拟列表的高度由"itemHeight"属性设置。组件还可以设置视口的高度,这样我们可以确保虚拟列表不会占据整个页面。该组件主要包含一个名为"viewport"的DIV,该DIV包含一个具有高度为"virtualHeight"的虚拟化div。 您可以按照此示例进行开发自己的虚拟列表组件,并将其用于您的VueJS应用程序中。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值