【项目小tips】Vue2中如何使用虚拟列表

本文介绍了Vue2中使用虚拟列表来优化性能的方法,讲解了虚拟列表的原理,手把手教你如何手写虚拟列表组件,并演示了使用vue-virtual-scroll-list插件快速实现虚拟列表的步骤,帮助前端开发者提升大型列表渲染效率。
摘要由CSDN通过智能技术生成

前言

本系列主要整理前端项目中需要掌握的知识点。本节介绍Vue2中如何使用虚拟列表。


一、使用场景

在项目中,有些请求可能一次性返回上千条信息,这是如果使用v-for循环创建dom节点,创建上千条节点将消耗大量的性能,且不利于首屏加载。
在这里插入图片描述

二、虚拟列表

以上的问题可以用虚拟列表来解决。虚拟列表的基本思路是,**在展示区只展示n个dom元素,而dom中展示哪部分内容则根据滚动条计算出来。**这样即使后端返回的数据再多,前端加载的dom元素也只有n个,利于首屏加载的同时也不会造成性能浪费。如图所示:
在这里插入图片描述
在图中,无论列表项内容到了多少项,DOM节点都只有10个,只不过是在不断更新而已。

三、虚拟列表的手写实现

  • 思路与代码来自:凉爽爽爽爽爽爽爽爽爽的vue2 与 vue3 虚拟列表实现

  • 首先定义一个组件,用于虚拟列表的展示。传入的参数包括items(展示信息数组)、size(每条信息所占高度)、shownumber(每个可视区域展示的信息条数)

    <List :items="items" :size="60" :shownumber="10"/>
    
  • 组件内部的盒子组成如下:外层是一个container、展示列表的盒子是list、list中用v-for遍历展示数据的数组showData,其中showData.length=shownumber。如下图所示:
    在这里插入图片描述

  • 并给container绑定滚动事件,当滚动事件发生后,计算滚动距离,用滚动距离除以每条数据的高度,即可得到被滚动条卷入的数据条数,因此showData数组的起始位置应该是this.start = Math.floor(scrollTop/this.size),终止位置为起始位置加上数组长度this.end = this.start+this.shownumber。

    computed: {
         
      // 最终筛选出的要展示的数据
      showData () {
         
        return this.items.slice(this.start, this.end)
      },
    }
    methods: {
         
      // 容器的滚动事件
      handleScroll () {
         
        // 获取容器顶部滚动的尺寸
        const scrollTop = this.$refs.container.scrollTop
        // 计算卷去的数据条数,用计算的结果作为获取数据的起始和结束下标
        // 起始的下标就是卷去的数据条数,向下取整
        this.start = Math.floor(scrollTop / this.size)
        // 结束的下标就是起始的下标加上要展示的数据条数
        this.end = this.start + this.shownumber
      }
    }
    

    在这里插入图片描述

  • 还需要对list盒子进行定位,否则滚动条滚动后,dom数据虽然发生了变化,但是同时list盒子中需要展示的前几条数据也被滚动条圈进去了,如上图虚线中。所以就需要将container设置为相对定位,list设置为绝对定位,每次start值变了,便重新计算top的值。

    <div
      class="list"
      :style="{ top: listTop }"
    >
    <script>
    export default {
         
      computed: {
         
        // 列表向上滚动时要动态改变 top 值
        listTop () {
         
          return this.start * this.size + 'px'
        }
      }
    }
    </script>
    

    在这里插入图片描述

  • 完整代码如下:
    App.vue中

    <!-- App.vue -->
    <template>
      <div id="app">
        <List
          :items="items"
          :size="60"
          :shownumber="10"
        />
      </div>
    </template>
    
    <script>
    import List from './components/List.vue'
    export default {
           
      name: 'App',
      components: {
           
        List,
      },
      computed: {
           
        // 要进行渲染的数据列表
        
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值