静态长列表优化
之前在商品模块的时候遇到一个这样的问题多个规格组合在一起的时候 规格列表就会很长并且每一个规格都会有不同的价格跟会员价图片等等信息,所以会造成每一条商品数据会十分的臃肿再加上多条的话,对于商品规格数据的增删改查操作的时候页面会卡顿白屏操作甚至会加载不出来等情况
针对这一反馈我们的长列表优化就来了
思路
外层div 设置一个可以滚动的固定高度的盒子,
内层一个盒子通过计算所有条数的高度和 用来设置高度让外层盒子可以滚动 可以通过绝对定位来设置 (作用:让内部滚动起来,计算整体高度)
内层另外一个盒子用来显示内容
对外层盒子绑定滚动事件得到滚动出去得高度 通过计算得到需要设置得数据 再设置内容的偏移量 跟滚动条高度持平 如此就达到了优化的目的了
css
<style>
.list-view {
height: 400px;
overflow: auto;
position: relative;
border: 1px solid #aaa;
}
.list-view-phantom {
position: absolute;
left: 0;
top: 0;
right: 0;
z-index: -1;
}
.list-view-content {
left: 0;
right: 0;
top: 0;
position: absolute;
/* transform: translateY(100px) !important; */
/* background: red; */
}
.list-view-item {
padding: 5px;
color: red;
line-height: 30px;
box-sizing: border-box;
background: #666;
margin: 10px 0;
}
</style>
html
<template>
<div class="list-view" @scroll="handleScroll">
<div
class="list-view-phantom"
:style="{
height: contentHeight
}"
/>
<div ref="content" class="list-view-content">
<div
v-for="(item, index) in visibleData"
class="list-view-item"
:style="{
height: itemHeight + 'px'
}"
>
<!-- {{ item.value }}
-->
<input v-model="item.value" type="text">
</div>
</div>
</div>
</template>
js
<script>
export default {
name: 'ListView',
props: {
itemHeight: {
type: Number,
default: 50
}
},
data() {
return {
visibleData: [], // 可视区域显示的数据
list: [] // 总数据
}
},
computed: {
contentHeight() {
return this.list.length * this.itemHeight + 'px'
}
},
mounted() {
this.updateVisibleData()
},
created() {
for (var i = 0; i < 1000; i++) {
this.list.push({
value: i
})
}
},
methods: { // 更新数据
updateVisibleData(scrollTop) {
scrollTop = scrollTop || 0
const visibleCount = Math.ceil(this.$el.clientHeight / this.itemHeight) // 计算可视区域显示的条数
console.log(visibleCount)
const start = Math.floor(scrollTop / this.itemHeight) // 截取数据的开始位置
const end = start + visibleCount // 截取数据的结束位置
this.visibleData = this.list.slice(start, end) // 截取的数据
console.log(this.visibleData)
// this.$refs.content.style.webkitTransform = `translateY(${start * this.itemHeight}px) `
this.$refs.content.style.top = `${start * this.itemHeight}px` // 内容展示区域跟滚动条位置平齐 这
},
// 绑定的滚动事件
handleScroll() {
const scrollTop = this.$el.scrollTop
this.updateVisibleData(scrollTop)
}
}
}
</script>