vue virtual list (虚拟列表)使用
为什么要使用virtual list
当有大量数据生成DOM并渲染时,界面会非常耗时且卡顿。通常会使用virtual list来解决问题,virtual list原理是只渲染可见区域,非可见区域不渲染。
不使用virtual list
一次性渲染全部
<template> <div ref="box" class="vl-box" :style="{ height: height + 'px' }"> <div :style="{ height: boxHeight + 'px' }"> <div class="vl-box-item" :style="{ height: rowHeight + 'px', lineHeight: rowHeight + 'px' }" v-for="item in data" :key="item.index" >{{ item }}</div> </div> </div> </template> <script> export default { data() { return { data: Array(100).fill('').map((v, i) => { return { index: i } }), height: 200, rowHeight: 30, } }, } </script> <style scoped> .vl-box { border: 2px solid #0094ff; overflow: auto; } .vl-box-item { box-sizing: border-box; border-bottom: 1px dotted red; } </style>> 复制代码
使用virtual list
固定virtual list高度
固定virtual list每一行高度,计算偏移量
<template> <div ref="box" class="vl-box" :style="{ height: height + 'px' }"> <div :style="{ height: boxHeight + 'px' }"> <div class="vl-box-item" :style="{ height: rowHeight + 'px', lineHeight: rowHeight + 'px', top: (index + offsetIndex) * rowHeight + 'px' }" v-for="(item,index) in offsetData" :key="item.index" >{{ item }}</div> </div> </div> </template> <script> export default { data() { return { data: Array(100).fill('').map((v, i) => { return { index: i } }), height: 200, rowHeight: 30, offset: 0, offsetIndex: 0 } }, computed: { boxHeight() { return this.data.length * this.rowHeight; }, offsetData() { let count = Math.ceil(this.height / this.rowHeight); let index = Math.floor(this.offset / this.rowHeight); this.offsetIndex = index; return this.data.slice(index, count + index); } }, mounted() { this.$refs.box.addEventListener('scroll', () => { this.offset = this.$refs.box.scrollTop; console.log(this.offset ) },false) }, } </script> <style scoped> .vl-box { border: 2px solid #0094ff; overflow: auto; } .vl-box > div { overflow: hidden; position: relative; } .vl-box > div > div { position: absolute; width: 100%; } .vl-box-item { box-sizing: border-box; border-bottom: 1px dotted red; } </style>>
作者:三体人1379号
链接:https://juejin.cn/post/7019850552418762760