vue-虚拟列表

什么是长列表

前端业务会涉及到数据量很大的且无法用分页进行加载的列表,我们一般叫做长列表,
完整的渲染长列表基本上很难达到业务的上的要求,非完整渲染长列表一般分为两种:
1.懒渲染:这个就是常见的无线滚动的,每次只渲染一部分(比如10条),等剩余部分滚到可见区域,就再渲染一部分。
2.可视区域渲染:只渲染可见部分,不可见部分不渲染。

虚拟列表就是采用的可视区渲染方式优化
 

虚拟列表实现原理 
 

虚拟列表(Virtual List),是一种长列表优化方案,是可视区渲染列表。其两个重要的概念:

  • 可滚动区域:假设有1000条数据,每个列表项的高度是30,那么可滚动的区域的高度就是1000*30。当用户改变列表的滚动条的当前滚动值的时候,会造成可见区域的内容的变更。
  • 可见区域:比如列表的高度是300,右侧有纵向滚动条可以滚动,那么视觉可见的区域就是可见区域。

实现原理

思路就是用vue的for循环渲染列表,自己手动加一个滚动条,然后通过监听scroll,算出应该显示到第几个,通过计算属性截取显示的数据,直接上代码

    <!-- 列表元素 使用相对定位 -->
    <div class="projectInfo" @scroll="scrollListener" ref="listWrap">

      <!-- 设置一个不可见元素撑起这个列表 让列表的滚动条出现 -->
      <div class="scroll-bar" ref="scrollBar"></div>
      <!-- 列表的可见元素 使用绝对定位,left、right、top设置为0 -->
      <div class="projectInfoBox" ref="list">
        <div class="productEach" @click="addShopping(item)" v-for="item in showList" :key="item.id">
          <div class="productImg">
            <img v-show="userInfo.userInfo.yw_type == 2" src="@/icon/catering.png" alt="" />
            <img v-show="userInfo.userInfo.yw_type == 1" src="@/icon/product.png" alt="" />
          </div>
          <!-- <div class="productText">{{ item.barcode }}</div> -->
          <div class="productText">
            <p>{{ item.name }}</p>
          </div>
          <div class="productDO">
            <p class="textMoney">¥{{ item.price }}</p>
          </div>
        </div>
      </div>
<script setup>
import {
  onMounted,
  ref,
  computed,
} from 'vue'
//首页的虚拟列表参数
let listWrap = ref(null)//列表元素
let itemHeight = ref(165) //每列元素的高度
let showNum = ref(30) //第一次显示多少元素
let scrollBar = ref(null) //虚拟滚动条
let list = ref(null) //超长显示的长度
let start = ref(0) //开始下标
let end = ref(24) //结束下标


onMounted(async () => {
//计算滚动容器高度
listWrap.value.height = itemHeight.value * showNum.value + 'px' //计算出
//计算总的数据需要的高度,构造滚动条
scrollBar.value.height =itemHeight.value * ProductList.ProductList.length + 'px'

})


//显示的商品
const showList = computed(() => {
    //ProductList 后端拿到的1万条数据  进行数据截取
  let arr = ProductList.slice(start.value, end.value)
  if (arr.length != 0) {
    //arr长度不等于0 就隐藏loading
    SettingStore.settingLoading(false)
  }
  return arr
})
//滚动事件
const scrollListener = () => {
  //获取滚动高度
  let scrollTop = listWrap.value.scrollTop
  //开始数据的索引
  start.value = Math.floor(scrollTop / itemHeight.value) * 6
  //结束索引
  end.value = start.value + showNum.value
  //绝对定位对相对定位的偏移量
  list.value.style.top = (start.value / 6) * itemHeight.value + 'px'
}

css就根据 你们的需求去操作吧。

 

<think>嗯,用户想了解如何使用vue-virtual-scroller解决虚拟列表的问题。首先,我需要回忆一下虚拟列表的概念和常见的问题。虚拟列表主要是为了优化长列表的渲染性能,只渲染可视区域内的元素,减少DOM节点数量,提升性能。 接下来,vue-virtual-scroller这个库,我记得是Vue生态中的一个组件,专门用来处理大量数据的滚动列表。应该先介绍它的基本作用,比如动态渲染可见项,避免内存和性能问题。然后需要说明它的适用场景,比如聊天记录、大型表格等。 然后,可能需要分点讲解它的核心原理。比如动态计算可视区域,只渲染可见元素,以及动态调整滚动条高度。这里要注意用简单易懂的语言,避免太技术化的术语,但又要准确。 接着,用户可能想知道怎么安装和使用。应该给出具体的安装命令,比如npm install或者yarn add。然后提供一个基本的使用示例,包括引入组件、注册,以及模板中的使用方式。这里要注意代码的格式,使用正确的Vue语法,同时可能需要解释每个属性的作用,比如items是数据源,item-size是每个项的高度,key-field的作用等。 然后,可能需要提到一些常用的属性和事件,比如除了items和item-size,还有page-mode,buffer等,这些属性如何影响性能和行为。事件比如resize、visible等,用户可能需要监听这些事件来处理特定的逻辑。 高级用法部分,可能需要讲动态高度的处理,因为实际应用中每个项的高度可能不一致。这时候需要使用DynamicScroller组件,并提供一个示例代码,展示如何动态计算高度。同时,可以提到无限滚动加载的实现,结合分页请求数据,这里需要举例子,比如滚动到底部时加载更多数据,使用@scroll-end事件。 性能优化方面,可以强调避免复杂的计算和频繁的DOM操作,使用虚拟滚动本身的优势,以及合理使用key-field来保证diff效率。可能还需要提醒用户注意数据更新的处理,比如使用Vue的响应式方法来更新数据源。 最后,要总结一下vue-virtual-scroller的优势,比如提升性能,减少内存占用,支持动态高度,以及与Vue生态的良好集成。可能还要比较一下其他虚拟滚动库,比如vue-virtual-scroll-list,说明各自的适用场景。 在写作过程中,需要确保步骤清晰,代码示例正确,并且语言口语化,避免生硬。同时,注意使用中文术语,比如“组件”、“属性”、“事件”等,保持一致性。可能还需要检查是否有遗漏的重要功能或常见问题,比如如何处理滚动位置保持,或者与Vue3的兼容性,确保信息准确。</think>我来分步骤为你讲解`vue-virtual-scroller`实现虚拟列表的原理和使用方法: **一、核心原理** 1. **视窗计算**:实时计算容器可视区域范围(上/下边界位置) 2. **动态渲染**:仅渲染可视区域内的列表项(约占总数5-10%) 3. **占位填充**:用空白div撑起不可见区域的滚动空间 4. **位置映射**:通过transform: translateY保持滚动位置正确性 **二、基础使用(Vue3示例)** ```bash npm install vue-virtual-scroller ``` ```vue <script setup> import { RecycleScroller } from 'vue-virtual-scroller' const items = Array.from({length: 10000}, (_, i) => ({ id: i, text: `Item ${i}` })) </script> <template> <RecycleScroller :items="items" :item-size="50" key-field="id" class="scroller" > <template v-slot="{ item }"> <div class="item">{{ item.text }}</div> </template> </RecycleScroller> </template> <style> .scroller { height: 400px; } .item { height: 50px; padding: 12px; border-bottom: 1px solid #eee; } </style> ``` **三、核心属性说明** | 属性 | 类型 | 说明 | 默认值 | |---------------|--------|-------------------------------|---------| | items | Array | 数据源数组 | - | | item-size | Number | 预估行高(px) | - | | key-field | String | 唯一标识字段
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值