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

一、概述

在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>
相关推荐
郭尘帅6662 小时前
vue3基础学习(上) [简单标签] (vscode)
前端·vue.js·学习
njsgcs2 小时前
opencascade.js stp vite webpack 调试笔记
开发语言·前端·javascript
T0uken2 小时前
【前端】:单 HTML 去除 Word 批注
前端·html·word
st紫月3 小时前
用vue和go实现登录加密
前端·vue.js·golang
岁岁岁平安3 小时前
Vue3学习(组合式API——计算属性computed详解)
前端·javascript·vue.js·学习·computed·计算属性
HWL56794 小时前
Express项目解决跨域问题
前端·后端·中间件·node.js·express
刺客-Andy4 小时前
React 第三十九节 React Router 中的 unstable_usePrompt Hook的详细用法及案例
前端·javascript·react.js
Go_going_4 小时前
【js基础笔记] - 包含es6 类的使用
前端·javascript·笔记
浩~~5 小时前
HTML5 浮动(Float)详解
前端·html·html5
AI大模型顾潇6 小时前
[特殊字符] 本地大模型编程实战(29):用大语言模型LLM查询图数据库NEO4J(2)
前端·数据库·人工智能·语言模型·自然语言处理·prompt·neo4j