当前位置:首页 > 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实现oauth

vue实现oauth

Vue 实现 OAuth 的步骤 安装必要的依赖 确保项目中安装了 axios 和 vue-router。OAuth 通常需要发送 HTTP 请求和处理路由跳转。 npm install axios…

vue实现换肤

vue实现换肤

使用 CSS 变量实现换肤 在 Vue 项目中,可以通过 CSS 变量(Custom Properties)动态切换主题色。CSS 变量可以在运行时修改,适合实现换肤功能。 定义全局 CSS 变量:…

vue实现slot

vue实现slot

Vue 中的 Slot 实现方法 Vue 的 slot 是一种内容分发机制,允许父组件向子组件插入内容。以下是几种常见的 Slot 实现方式: 默认 Slot 子组件通过 <slot>…

vue ref实现

vue ref实现

Vue 中 ref 的实现 在 Vue 中,ref 是一个用于创建响应式引用的 API,适用于基本类型和对象。以下是 ref 的核心实现原理和使用方法。 基本实现原理 ref 通过 Reactive…

vue实现路径

vue实现路径

Vue 实现路径的方法 在 Vue 中实现路径管理通常涉及 Vue Router 的使用,以下是一些常见的实现方法: 安装 Vue Router 通过 npm 或 yarn 安装 Vue Route…

vue 实现弹窗

vue 实现弹窗

Vue 实现弹窗的方法 在 Vue 中实现弹窗功能可以通过多种方式完成,以下是几种常见的方法: 使用组件和 v-if/v-show 控制显示 创建一个独立的弹窗组件,通过 v-if 或 v-show…