当前位置: 首页 > news >正文

vue3虚拟列表

virtualList

<template><div class="virtual-list-container" ref="containerRef" @scroll="handleScroll"><!-- 这个元素撑开滚动条,高度为所有数据的总高度 --><div class="virtual-list-phantom" :style="{ height: totalHeight + 'px' }"></div><!-- 这个元素承载实际渲染的列表项,通过 transform 进行偏移 --><div class="virtual-list-content" :style="{ transform: `translateY(${offsetY}px)` }"><divv-for="item in visibleData":key="item.id"class="virtual-list-item":style="{ height: itemHeight + 'px' }"><!-- 使用插槽允许自定义列表项内容 --><slot name="scope" :scope="item"></slot></div></div></div>
</template>
<script setup>
import { ref, computed, onMounted } from 'vue'// 定义组件属性
const props = defineProps({data: {type: Array,required: true},itemHeight: {type: Number,required: true},containerHeight: {type: Number,required: true},buffer: {type: Number,default: 5}
})const containerRef = ref() // 容器DOM引用
const scrollTop = ref(0) // 当前滚动距离// 计算总高度(所有数据项的高度和)
const totalHeight = computed(() => props.data.length * props.itemHeight)// 计算可视区域能容纳的项目数量
const visibleCount = computed(() => Math.ceil(props.containerHeight / props.itemHeight))// 计算起始索引(从第几条数据开始渲染)
const startIndex = computed(() => {return Math.floor(scrollTop.value / props.itemHeight)
})// 计算结束索引(考虑到缓冲区和可视数量)
const endIndex = computed(() => {return Math.min(props.data.length, startIndex.value + visibleCount.value + props.buffer * 2)
})// 计算Y轴偏移量,确保当前起始项位于可视区域顶部
const offsetY = computed(() => startIndex.value * props.itemHeight)// 计算当前真正需要渲染的可见数据片段
const visibleData = computed(() => {const start = Math.max(0, startIndex.value - props.buffer)return props.data.slice(start, endIndex.value)
})// 处理滚动事件,更新scrollTop
const handleScroll = (e) => {scrollTop.value = e.target.scrollTop
}onMounted(() => {// 可选:确保容器高度正确设置if (containerRef.value) {containerRef.value.style.height = props.containerHeight + 'px'}
})
</script>
<style scoped>
.virtual-list-container {position: relative;overflow-y: auto; /* 允许垂直滚动 */width: 100%;
}
.virtual-list-phantom {position: absolute;left: 0;top: 0;right: 0;z-index: -1; /* 置于底层,不干扰内容 */
}
.virtual-list-content {position: absolute; /* 绝对定位,脱离文档流 */left: 0;right: 0;top: 0;
}
.virtual-list-item {/* 你的列表项样式,确保高度与itemHeight属性一致 */box-sizing: border-box;
}
</style>

使用组件

	<template><div class="page-className"><VirtualList :data="list" :itemHeight="50" :containerHeight="400"><template #scope="{ scope }"><div>{{ scope.name }}</div></template></VirtualList></div>
</template>
<script setup name="ComponentName">
import { onMounted, ref } from 'vue'
import VirtualList from '@/components/virtualList/index.vue'const list = ref([])/*** 生成一个指定长度的数组* @param {number} length - 需要生成的数组长度* @param {Function} [generatorFn] - 可选参数,用于生成每个数组元素的函数。该函数接收当前元素的索引作为参数。* @returns {Array} 返回一个新数组*/
function generateArray(length, generatorFn) {// 基础参数校验if (typeof length !== 'number' || length < 0 || !Number.isInteger(length)) {throw new TypeError('参数 length 必须是一个非负整数')}// 使用 Array.from 创建数组。{ length: length } 创建一个指定长度的类数组对象。// 第二个参数是一个映射函数,它接收当前值(下划线 _ 表示未使用)和索引 index。return Array.from({ length: length },(_, index) => (generatorFn ? generatorFn(index) : index) // 如果提供了 generatorFn,则使用它生成元素,否则使用索引值)
}
onMounted(() => {list.value = generateArray(10000, (i) => {return {name: i + 1}})console.log(list.value)
})
</script>
<style scoped lang="scss"></style>
http://www.dtcms.com/a/535855.html

相关文章:

  • vue之异步更新队列
  • 软文推广有哪些企业关键词优化推荐
  • REFramework下载和安装教程(附安装包)
  • 散户如何做手机T0程序化交易(上)
  • JMeter:执行顺序与作用域
  • Java的自定义异常,throw和throws的对比
  • 哪些知名网站用wordpress建设摩托车是名牌吗
  • Apache JMeter下载和安装图文教程(附安装包,适合新手)
  • MySQL查询字段只有中文的数据
  • 基于Docker、Solr和FastAPI的商品搜索微服务架构设计
  • Woodpecker CI 轻量级持续集成系统深度解析
  • 2.2.2.2 大数据方法论与实践指南-Java Web CI/CD 工具
  • 快速学习React-(第二天)-完成井字棋游戏
  • 石家庄网站开发培训家教网站开发公司
  • 如何制作网址快捷方式深圳网站优化怎么做
  • 聊聊Spark的分区
  • 国产之光:奥威BI的AI数据分析平台,重新定义商业智能
  • Android ContentProvier
  • uni-app OCR图文识别
  • 二叉树的多种遍历方式
  • Vue3 + Electron + Node.js 桌面项目完整开发指南
  • 【Node.js】Node.js 模块系统
  • 古籍影文公开古籍OCR检测数据集VOC格式共计8个文件
  • 网站的对比哪些网站是做免费推广的
  • 网站建设的整体流程有哪些?建筑工程网站建站方案
  • 区块链的密码学基石:沙米尔秘密共享(SSS)数学原理详解
  • 单例模式详解:从基础到高级的八种实现方式
  • 改版网站收费wordpress国人主题
  • web3.0是什么
  • 计网:网络层