当前位置:首页 > VUE

vue虚拟滚动实现

2026-01-16 18:33:08VUE

vue虚拟滚动实现

虚拟滚动是一种优化长列表渲染性能的技术,通过仅渲染可视区域内的元素来减少DOM节点数量。以下是基于Vue的虚拟滚动实现方法:

使用第三方库

推荐使用成熟的虚拟滚动库如vue-virtual-scrollervue-virtual-scroll-list

vue虚拟滚动实现

安装vue-virtual-scroller

npm install vue-virtual-scroller

基本使用示例:

vue虚拟滚动实现

<template>
  <RecycleScroller
    class="scroller"
    :items="items"
    :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'
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'

export default {
  components: { RecycleScroller },
  data() {
    return {
      items: Array(10000).fill().map((_, i) => ({ id: i, name: `Item ${i}` }))
    }
  }
}
</script>

<style>
.scroller {
  height: 400px;
}
.item {
  height: 50px;
  padding: 10px;
}
</style>

手动实现虚拟滚动

对于需要自定义实现的情况,可通过以下方式:

<template>
  <div class="virtual-list" @scroll="handleScroll" ref="container">
    <div class="phantom" :style="{ height: totalHeight + 'px' }">
      <div 
        class="content" 
        :style="{ transform: `translateY(${startOffset}px)` }"
      >
        <div 
          v-for="item in visibleData" 
          :key="item.id" 
          class="list-item"
          :style="{ height: itemSize + 'px' }"
        >
          {{ item.value }}
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    listData: Array,
    itemSize: {
      type: Number,
      default: 50
    },
    visibleCount: {
      type: Number,
      default: 10
    }
  },
  data() {
    return {
      startIndex: 0,
      endIndex: this.visibleCount
    }
  },
  computed: {
    totalHeight() {
      return this.listData.length * this.itemSize
    },
    visibleData() {
      return this.listData.slice(this.startIndex, this.endIndex)
    },
    startOffset() {
      return this.startIndex * this.itemSize
    }
  },
  methods: {
    handleScroll() {
      const scrollTop = this.$refs.container.scrollTop
      this.startIndex = Math.floor(scrollTop / this.itemSize)
      this.endIndex = this.startIndex + this.visibleCount
    }
  }
}
</script>

<style>
.virtual-list {
  height: 500px;
  overflow-y: auto;
  position: relative;
}
.phantom {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
}
.content {
  position: absolute;
  left: 0;
  right: 0;
}
.list-item {
  border-bottom: 1px solid #eee;
  display: flex;
  align-items: center;
  padding: 0 16px;
}
</style>

性能优化要点

  • 使用transform代替top进行定位,避免重排
  • 合理设置缓冲区,提前加载可视区域外的部分数据
  • 对于动态高度项目,需要实现尺寸测量和位置缓存
  • 使用requestAnimationFrame优化滚动事件处理

动态高度处理

对于不定高度的项目,需要先测量并缓存高度:

// 在mounted中测量初始高度
mounted() {
  this.cachedHeights = []
  this.$nextTick(() => {
    const items = this.$el.querySelectorAll('.list-item')
    items.forEach((item, index) => {
      this.cachedHeights[index] = item.getBoundingClientRect().height
    })
    this.calculatePositions()
  })
},
methods: {
  calculatePositions() {
    this.positions = this.listData.map((_, index) => {
      const prevPosition = this.positions[index - 1] || { top: 0, bottom: 0 }
      return {
        top: prevPosition.bottom,
        bottom: prevPosition.bottom + (this.cachedHeights[index] || this.defaultHeight)
      }
    })
    this.totalHeight = this.positions[this.positions.length - 1].bottom
  }
}

以上实现方式可根据具体需求选择,第三方库适合快速实现,手动实现则提供更高灵活性。

标签: vue
分享给朋友:

相关文章

vue的实现原理

vue的实现原理

Vue 的实现原理 Vue 是一个渐进式 JavaScript 框架,其核心实现原理主要包括响应式系统、虚拟 DOM、模板编译和组件化机制。 响应式系统 Vue 使用 Object.definePr…

vue伪函数实现

vue伪函数实现

Vue 伪函数实现方法 伪函数(Mock Function)在 Vue 中常用于测试或模拟某些逻辑,以下是几种常见的实现方式: 使用 Jest 的 jest.fn() 在单元测试中,可以通过 Je…

vue 页签实现

vue 页签实现

Vue 页签实现方法 在 Vue 中实现页签功能通常涉及动态组件、路由或状态管理。以下是几种常见的实现方式: 使用动态组件 通过 Vue 的 <component> 动态组件结合 v-…

vue怎么实现页面返回

vue怎么实现页面返回

Vue 实现页面返回的方法 在 Vue 中实现页面返回功能,可以通过以下几种方式完成,具体取决于项目使用的路由模式和技术栈。 使用 Vue Router 的编程式导航 通过 this.$router…

vue实现点击页面切换

vue实现点击页面切换

实现点击页面切换功能 在Vue中实现点击页面切换功能,可以通过路由跳转或组件动态渲染两种方式完成。以下是具体实现方法: 使用Vue Router实现页面跳转 安装Vue Router后,在项目中…

vue实现滚动截屏

vue实现滚动截屏

实现滚动截屏的基本思路 滚动截屏通常指对超出可视区域的长页面进行完整截图。在Vue中,可以通过结合DOM操作、Canvas绘制及第三方库实现。以下是具体方法: 使用html2canvas库实现…