当前位置:首页 > VUE

vue虚拟滚动列表实现

2026-02-20 19:22:18VUE

Vue 虚拟滚动列表实现方法

虚拟滚动(Virtual Scrolling)通过仅渲染可见区域内的元素来优化长列表性能,减少 DOM 节点数量。以下是 Vue 中实现虚拟滚动的几种方案:

使用第三方库(推荐)

  1. vue-virtual-scroller
    安装依赖:

    vue虚拟滚动列表实现

    npm install vue-virtual-scroller

    示例代码:

    vue虚拟滚动列表实现

    <template>
      <RecycleScroller
        class="scroller"
        :items="list"
        :item-size="50"
        key-field="id"
      >
        <template v-slot="{ item }">
          <div class="item">{{ item.name }}</div>
        </template>
      </RecycleScroller>
    </template>
    
    <script>
    import { RecycleScroller } from 'vue-virtual-scroller';
    export default {
      components: { RecycleScroller },
      data() {
        return { list: [...] }; // 长列表数据
      }
    };
    </script>
    
    <style>
    .scroller { height: 400px; }
    .item { height: 50px; }
    </style>
  2. vue-virtual-scroll-grid
    适用于网格布局,用法类似,但支持横向和纵向滚动。

手动实现虚拟滚动

若需自定义逻辑,可通过计算可见区域索引实现:

<template>
  <div class="viewport" @scroll="handleScroll" ref="viewport">
    <div class="scroll-placeholder" :style="{ height: totalHeight + 'px' }">
      <div
        v-for="item in visibleItems"
        :key="item.id"
        class="item"
        :style="{ transform: `translateY(${item.offset}px)` }"
      >
        {{ item.content }}
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      allItems: [...], // 完整列表
      itemHeight: 50,
      startIndex: 0,
      endIndex: 0,
      viewportHeight: 0
    };
  },
  computed: {
    totalHeight() {
      return this.allItems.length * this.itemHeight;
    },
    visibleItems() {
      return this.allItems.slice(this.startIndex, this.endIndex).map((item, i) => ({
        ...item,
        offset: (this.startIndex + i) * this.itemHeight
      }));
    }
  },
  mounted() {
    this.viewportHeight = this.$refs.viewport.clientHeight;
    this.calculateRange();
  },
  methods: {
    handleScroll() {
      this.calculateRange();
    },
    calculateRange() {
      const scrollTop = this.$refs.viewport.scrollTop;
      this.startIndex = Math.floor(scrollTop / this.itemHeight);
      this.endIndex = Math.min(
        this.startIndex + Math.ceil(this.viewportHeight / this.itemHeight) + 2,
        this.allItems.length
      );
    }
  }
};
</script>

<style>
.viewport {
  height: 400px;
  overflow-y: auto;
  position: relative;
}
.scroll-placeholder {
  position: relative;
}
.item {
  position: absolute;
  width: 100%;
  height: 50px;
}
</style>

关键优化点

  1. 动态高度支持
    若列表项高度不固定,需使用动态测量(如 IntersectionObserver)或预计算高度。
  2. 滚动节流
    使用 requestAnimationFrame 或 Lodash 的 throttle 减少滚动事件频率。
  3. SSR 兼容
    虚拟滚动通常依赖客户端 DOM 操作,需在 SSR 场景下降级处理。

性能对比

  • 原生列表:渲染 10,000 项时,DOM 节点数 10,000+,内存占用高。
  • 虚拟列表:仅渲染 20-30 项(视窗口大小),DOM 节点数减少 99%+。

根据项目需求选择合适方案,复杂场景推荐使用成熟库。

标签: 列表vue
分享给朋友:

相关文章

vue怎么实现文件树

vue怎么实现文件树

Vue 实现文件树的方法 使用递归组件 递归组件是处理嵌套数据结构的理想方式。文件树通常包含文件夹和文件的嵌套结构,适合用递归组件实现。 <template> <ul>…

vue实现详情

vue实现详情

Vue 实现详情页的常见方法 使用动态路由 在 Vue Router 中配置动态路由参数,通过 $route.params 获取详情 ID。示例路由配置: { path: '/detail/:i…

vue 实现回复

vue 实现回复

Vue 实现回复功能 在 Vue 中实现回复功能通常涉及表单提交、数据绑定和列表渲染。以下是实现步骤和代码示例: 数据绑定与表单 <template> <div>…

vue实现试卷

vue实现试卷

Vue实现试卷系统的基本思路 使用Vue.js构建试卷系统需要结合组件化开发、状态管理和后端数据交互。核心功能包括题目展示、答题逻辑、计时器和提交答案。 核心功能模块划分 试卷组件结构 试卷容器组…

vue实现watch

vue实现watch

监听数据变化 在Vue中,watch用于监听响应式数据的变化并执行回调函数。基本语法如下: watch: { propertyName(newValue, oldValue) { //…

黑马vue实现

黑马vue实现

以下是关于使用 Vue.js 实现黑马相关功能或项目的关键方法和实践指南: 环境配置与项目初始化 安装最新版 Vue CLI 或使用 Vite 创建项目: npm create vue@lates…