vue长列表虚拟滚动封装

<template> <div ref="virtual" class="virtual-empty" :style="{ height: height + 'px' }"> <div class="virtual-container" :style="{ height: clacHeight + 'px', minHeight: height + 'px' }"> <slot :topIndex="topIndex" :bottomIndex="bottomIndex"></slot> </div> </div> </template>
<script> export default { name: 'VirtualScroll', props: { height: { required: true, type: Number, default: 0 }, childHeight: { required: true, type: Number, default: 0 }, offset: { required: false, type: Number, default: 0 }, data: { required: true, type: Array, default: () => [] } }, data() { return { topIndex: 0, bottomIndex: 0, totalHeight: 0, } }, mounted() { this.initScroll() }, beforeDestroy() { this.virtualDom.removeEventListener('scroll', this.debounceScroll, {passive: true}) this.virtualDom = null }, computed: { clacHeight() { let length = this.data.length let height = length > 0 ? length * this.childHeight > this.height ? length * this.childHeight : this.height : this.height length = null return height } }, methods: { initScroll() { if(!this.height) return if(!this.childHeight) return this.virtualDom = this.$refs['virtual'] this.debounceScroll = _.debounce(this.scroll, 16) this.virtualDom.addEventListener('scroll', this.debounceScroll, {passive: true}) this.scroll() }, scroll() { let scrollTop = this.virtualDom.scrollTop this.topIndex = Math.floor((scrollTop - this.offset > 0 ? scrollTop - this.offset : scrollTop) / this.childHeight); this.bottomIndex = this.topIndex + Math.ceil((this.height + this.offset) / this.childHeight) scrollTop = null }, // 重制滚动高度 resetScrollTop() { this.virtualDom.scrollTop = 0 } } } </script>
<style lang="less"> .virtual-empty { overflow-y: scroll; } .virtual-container { position: relative; width: 100%; } </style>
上一篇:移动端 记录滚动位置


下一篇:2021-08-24