vue virtual list (虚拟列表)使用
为什么要使用virtual list当有大量数据生成DOM并渲染时,界面会非常耗时且卡顿。通常会使用virtual list来解决问题,virtual list原理是只渲染可见区域,非可见区域不渲染。不使用virtual list一次性渲染全部<template><div ref="box" class="vl-box" :style="{ height: height + 'p
·
为什么要使用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>>
更多推荐
已为社区贡献3条内容
所有评论(0)