当前位置:首页 > VUE

vue虚拟滚动列表实现

2026-02-20 19:22:18VUE

Vue 虚拟滚动列表实现方法

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

使用第三方库(推荐)

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

    npm install vue-virtual-scroller

    示例代码:

    <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 实现递归组件的方法 在 Vue 中实现递归组件通常用于处理树形结构数据(如菜单、评论列表、文件目录等)。以下是具体实现方法: 定义递归组件 通过 name 选项让组件可以递归调用自身:…

vue 实现递归

vue 实现递归

Vue 实现递归组件的方法 在 Vue 中实现递归组件通常用于处理树形结构数据,例如菜单、评论列表或文件目录。以下是实现递归组件的关键步骤: 定义递归组件 递归组件需要设置 name 属性,以便在模…

computed vue 实现

computed vue 实现

computed 在 Vue 中的基本用法 Vue 的 computed 属性用于声明依赖于其他数据的计算属性。当依赖的数据变化时,计算属性会自动重新计算并缓存结果。 export defau…

vue observer实现

vue observer实现

Vue Observer 实现原理 Vue 的响应式系统核心是通过 Object.defineProperty(Vue 2)或 Proxy(Vue 3)实现的 Observer 模式。以下是关键实现细…

vue 实现图钉

vue 实现图钉

实现图钉效果的步骤 在Vue中实现图钉(固定位置)效果,可以通过CSS的position: sticky属性或监听滚动事件动态修改元素样式。以下是两种常见方法: 方法一:使用CSS的positio…

vue 实现音乐

vue 实现音乐

Vue 实现音乐播放功能 在 Vue 中实现音乐播放功能,可以通过 HTML5 的 <audio> 元素或第三方库如 howler.js 来实现。以下是两种方法的详细步骤: 使用 HTM…