虚拟滚动列表(每一项固定高度)

一、概述

在Web开发中,当需要展示大量数据时,直接渲染所有数据会导致页面性能下降,尤其是在列表项较多的情况下。虚拟滚动(Virtual Scrolling)是一种优化技术,它通过只渲染当前可见的列表项来减少DOM节点的数量,从而提高页面的渲染性能。

本文将介绍如何实现一个简单的虚拟滚动列表,其中每个列表项的高度是固定的。我们将使用Vue.js框架来实现这一功能,并结合HTML和CSS来完成布局和样式。

二、效果图

三、具体实现

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>虚拟滚动列表(每一项固定高度)</title>
  <style>
    .virtual-scroll-container {
      height: 300px;
      overflow-y: auto;
      border: 1px solid #ccc;
      position: relative;
    }

    .virtual-scroll-list {
      position: relative;
    }

    .virtual-scroll-item {
      position: absolute;
      width: 100%;
      box-sizing: border-box;
      border-bottom: 1px solid #eee;
      padding: 10px;
    }
  </style>
</head>

<body>
  <div id="app">
    <h1>虚拟滚动列表Demo</h1>
    <div class="virtual-scroll-container" @scroll="handleScroll">
      <div class="virtual-scroll-list" :style="{ height: totalHeight + 'px' }">
        <div class="virtual-scroll-item" v-for="item in visibleItems" :key="item.id"
          :style="{ top: item.top + 'px', height: itemHeight + 'px' }">
          {{ item.content }}
        </div>
      </div>
    </div>
  </div>

  <script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue/2.6.14/vue.min.js"></script>
  <script>
    new Vue({
      el: '#app',
      data() {
        return {
          items: [], // 数据列表
          itemHeight: 50, // 每个项的高度
          visibleCount: 10, // 可见的项数
          scrollTop: 0, // 滚动位置
        };
      },
      computed: {
        // 计算总高度
        totalHeight() {
          return this.items.length * this.itemHeight;
        },
        // 计算起始索引
        startIndex() {
          return Math.floor(this.scrollTop / this.itemHeight);
        },
        // 计算结束索引
        endIndex() {
          return Math.min(
            this.startIndex + this.visibleCount,
            this.items.length - 1
          );
        },
        // 计算可见的项
        visibleItems() {
          return this.items
            .slice(this.startIndex, this.endIndex + 1)
            .map((item, index) => ({
              ...item,
              top: (this.startIndex + index) * this.itemHeight,
            }));
        },
      },
      methods: {
        // 处理滚动事件
        handleScroll(event) {
          this.scrollTop = event.target.scrollTop;
        },
      },
      mounted() {
        // 初始化数据
        for (let i = 0; i < 1000; i++) {
          this.items.push({
            id: i,
            content: `Item ${i + 1} -+-+-+-测试数据-+-+-+-`,
          });
        }
      },
    });
  </script>
</body>

</html>
相关推荐
豆苗学前端11 分钟前
你所不知道的前端知识,html篇(更新中)
前端·javascript·面试
一 乐12 分钟前
绿色农产品销售|基于springboot + vue绿色农产品销售系统(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·后端·宠物
zzjyr12 分钟前
Webpack 生命周期原理深度解析
前端
xiaohe060115 分钟前
💘 霸道女总裁爱上前端开发的我
前端·游戏开发·trae
sophie旭18 分钟前
内存泄露排查之我的微感受
前端·javascript·性能优化
k***19526 分钟前
Spring 核心技术解析【纯干货版】- Ⅶ:Spring 切面编程模块 Spring-Instrument 模块精讲
前端·数据库·spring
rgeshfgreh1 小时前
Spring事务传播机制深度解析
java·前端·数据库
Hilaku2 小时前
我用 Gemini 3 Pro 手搓了一个并发邮件群发神器(附源码)
前端·javascript·github
IT_陈寒2 小时前
Java性能调优实战:5个被低估却提升30%效率的JVM参数
前端·人工智能·后端
快手技术2 小时前
AAAI 2026|全面发力!快手斩获 3 篇 Oral,12 篇论文入选!
前端·后端·算法