当前位置:首页 > 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 购物按钮实现方法 基础按钮实现 使用 Vue 的模板语法创建基础按钮组件,绑定点击事件处理购物逻辑: <template> <button @click="addToC…

vue 实现单选

vue 实现单选

使用 v-model 绑定单选值 在 Vue 中,可以通过 v-model 绑定单选按钮的值。定义一个响应式数据(如 selectedOption),并将其与单选按钮的 value 属性关联。…

vue底部实现

vue底部实现

Vue 底部实现方法 在 Vue 项目中实现底部布局可以通过多种方式完成,以下是一些常见的方法: 使用固定定位 将底部元素固定在页面底部,适用于单页应用或需要始终显示的底部栏。 <temp…

vue实现tabs

vue实现tabs

Vue实现Tabs组件的方法 使用动态组件和v-for指令 在Vue中创建Tabs组件可以通过动态组件和v-for指令实现。定义一个包含tab标题和内容的数组,使用v-for渲染tab标题,并通过点击…

vue实现复制

vue实现复制

Vue 实现复制功能 在 Vue 中实现复制功能可以通过多种方式完成,以下是几种常见的方法: 方法一:使用 Clipboard API Clipboard API 是现代浏览器提供的一种原生 AP…

vue 实现vshow

vue 实现vshow

Vue 实现 v-show 在 Vue 中,v-show 是一个常用的指令,用于根据条件控制元素的显示或隐藏。与 v-if 不同,v-show 不会移除 DOM 元素,而是通过 CSS 的 displ…