index.vue
<template>
<div class="virtual-list">
<VirtualScroll :listData="list" />
</div>
</template>
<script>
import VirtualScroll from './components/virtual-scroll.vue'
export default {
components: {
VirtualScroll,
},
data() {
return {
list: [
{
name: 'list1',
content: 'list1_content'
},
{
name: 'list2',
content: 'list2_content'
}, {
name: 'list3',
content: 'list3_content'
},
{
name: 'list4',
content: 'list7_content'
}
]
}
},
created(){
this.getData()
},
methods: {
getData(){
let list = []
for(let i = 0;i<100;i++){
list.push({
name:`gy_${i}不是第`,
content:`${i}_头🐖🐖🐖🐖`
})
}
this.list = list
}
}
}
</script>
virtual-scroll.vue
<template>
<div class="virtual-scroll" ref="virtualScroll">
<div class="content-background" :style="{ height: `${listHeight}px` }"></div>
<div class="content-list" :style="contentStyle">
<div class="list-item" v-for="(listItem, index) in virtualData" :Key="index"
:style="{ height: `${itemHeight}px` }">
<div>{{ listItem.name }}</div>
<div>{{ listItem.content }}</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
listData: {
type: Array,
default() {
return []
}
},
itemHeight: {
type: Number,
default: 60
}
},
data() {
return {
startIndex: 0,
contentBoxHeight: 0,
scrollTop: 0,
startOffset: 0
}
},
computed: {
// 列表总高度
listHeight() {
return this.listData.length * this.itemHeight
},
virtualData() {
let endIndex = this.startIndex + this.showSize + 2
return this.listData.slice(this.startIndex, endIndex)
},
showSize() {
return Math.ceil(this.contentBoxHeight / this.itemHeight) // 可视区展示的list条数
},
contentStyle() {
const startOffset = this.startIndex * this.itemHeight
return {
// transform: `translate3d(0,${startOffset}px,0)`
transform: `translate3d(0,0,0)`
}
}
},
mounted() {
this.contentBoxHeight = this.$refs.virtualScroll.offsetHeight
this.$refs.virtualScroll.addEventListener('scroll', this.handlerScroll)
},
methods: {
handlerScroll(e) {
const { scrollTop } = e.target
this.scrollTop = scrollTop
this.startIndex = Math.floor(scrollTop / this.itemHeight) // 开始索引
// this.startOffset = scrollTop - (scrollTop % this.itemHeight)
// this.startOffset = this.startIndex ? (this.startIndex - 1) * this.itemHeight : this.startIndex * this.itemHeight
// this.startOffset = this.startIndex * this.itemHeight
console.log(scrollTop, this.$refs.virtualScroll.scrollTop, scrollTop % this.itemHeight, '滚动了---------')
}
}
}
</script>
<style lang="scss">
.virtual-scroll {
height: 600px;
width: 375px;
overflow: auto;
margin: 0 auto;
position: relative;
.content-list {
position: absolute;
top: 0;
left: 0;
width: 100%;
z-index: -1;
}
.list-item {
padding: 10px;
box-sizing: border-box;
border:1px solid #000;
}
}
</style>