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

一、概述

在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>
相关推荐
Jmyd012313 分钟前
用 Web VR 引擎搭建 3D 虚拟展厅:从素材上云到多端实时渲染的完整数据链路
前端·3d·vr·三维数字化
刘天远1 小时前
Agent成本核算实现:事件表、状态分布与Python归集
前端·数据库·人工智能·python
欣欣之王来了1 小时前
开发环境准备:Node.js、npm、VS Code安装配置
前端·学习·架构·项目·vue3教程
xiaolinudao1231 小时前
将多个 Excel 表格中的数据合并到单个表中|6 种实现方案全解析
java·前端·excel
LRL_2 小时前
跨平台 Node 模块安装指南:如何利用 pnpm/npm 配置`supportedArchitectures` 锁定平台依赖
前端·npm·node.js
EatFan2 小时前
React 项目踩坑实录:useEffect 闭包陷阱、Context 性能陷阱与 React 18 升级避坑排查手册
前端·javascript·react.js·react·react hooks·useeffect·闭包陷阱
风骏时光牛马3 小时前
企业业务运营信息数据库
前端
IT_陈寒3 小时前
Vue的数组更新把我坑惨了
前端·人工智能·后端
于航4 小时前
分层上下文压缩,幻觉检测,错误累积概要
前端
数据掘金4 小时前
鸿蒙统计的权限弹窗怎么适配?
前端