其他分享
首页 > 其他分享> > vue自定义实现虚拟化列表

vue自定义实现虚拟化列表

作者:互联网

 1使用

<ViualList :size="40" :remain="8" :dataList="dataList"> </ViualList>

size:每个列表的高度Height

remain:当前屏幕展示数据个数

dataList:当前数据

2自定义组件ViualList

根据size和remain确定内容区域height

根据size和dataList长度确定滚动条height

<!-- 主高度 -->   <div class="vitual-con" ref="vitualConRef" @scroll="handleScroll">     <!-- 滚动条 -->     <div class="scroll-bar" ref="scrollBarRef"></div>     <div       class="scroll-list"       ref="scrollListRef"       :style="{ 'padding-top': `${this.scrollTop}px` }"     >       <div         class="listItem"         v-for="item in visibleData"         :key="item.id"         :style="{ height: `${size}px` }"       >         {{ item.id + "." + item.value }}       </div>     </div>   </div>
......
 mounted() {
    //定义主屏幕高度
    this.$refs.vitualConRef.style.height = this.size * this.remain + "px";
    //定义滚动条高度
    this.$refs.scrollBarRef.style.height =
      this.size * this.dataList.length + "px";
  },
.vitual-con {   overflow-y: scroll;   position: relative; } .scroll-list {   position: absolute;   top: 0;   left: 0; }
 

控制当前页面只显示remain个数的数据可以根据滚动条来获取当前位置和数据

  handleScroll() {
      this.start = Math.floor(this.$refs.vitualConRef.scrollTop / this.size);
      this.end = this.start + this.remain;
    },

在字符串中截取start到end数据,优化效果则设置预留数据

computed: {
    visibleData() {
      let start = this.start - this.preveCount;
      let end = this.end + this.nextCount;
      return this.dataList.slice(start, end);
    },
    // 计算内容区域 当前距离顶部的距离----优化
    scrollTop() {
      return this.start * this.size - this.size * this.preveCount;
    },
    // 优化-----避免下方出现的空白和当用户快速滚动时,出现空白屏----解决:预留加载
    preveCount() {
      // 前面预留的个数---- 当前面的个数小于 8 个时,有几个就预留几个
      return Math.min(this.start, this.remain);
    },
    nextCount() {
      // 后面预先加载的个数
      return Math.min(this.end, this.dataList.length - this.end);
    },
  },

以下是完整代码

<template>
  <!-- 主高度 -->
  <div class="vitual-con" ref="vitualConRef" @scroll="handleScroll">
    <!-- 滚动条 -->
    <div class="scroll-bar" ref="scrollBarRef"></div>
    <div
      class="scroll-list"
      ref="scrollListRef"
      :style="{ 'padding-top': `${this.scrollTop}px` }"
    >
      <div
        class="listItem"
        v-for="item in visibleData"
        :key="item.id"
        :style="{ height: `${size}px` }"
      >
        {{ item.id + "." + item.value }}
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "ViualList",
  props: {
    size: {
      type: Number,
      default: 40,
    },
    remain: {
      type: Number,
      default: 8,
    },
    dataList: {
      type: Array,
      default: () => [],
    },
  },
  data() {
    return {
      start: 0,
      end: this.remain,
    };
  },
  computed: {
    visibleData() {
      let start = this.start - this.preveCount;
      let end = this.end + this.nextCount;
      return this.dataList.slice(start, end);
    },
    // 计算内容区域 当前距离顶部的距离----优化
    scrollTop() {
      return this.start * this.size - this.size * this.preveCount;
    },
    // 优化-----避免下方出现的空白和当用户快速滚动时,出现空白屏----解决:预留加载
    preveCount() {
      // 前面预留的个数---- 当前面的个数小于 8 个时,有几个就预留几个
      return Math.min(this.start, this.remain);
    },
    nextCount() {
      // 后面预先加载的个数
      return Math.min(this.end, this.dataList.length - this.end);
    },
  },
  mounted() {
    //定义主屏幕高度
    this.$refs.vitualConRef.style.height = this.size * this.remain + "px";
    //定义滚动条高度
    this.$refs.scrollBarRef.style.height =
      this.size * this.dataList.length + "px";
  },
  methods: {
    handleScroll() {
      // console.log(this.$refs.vitualConRef.scrollTop);
      this.start = Math.floor(this.$refs.vitualConRef.scrollTop / this.size);
      this.end = this.start + this.remain;
    },
  },
};
</script>

<style>
.vitual-con {
  overflow-y: scroll;
  position: relative;
}
.scroll-list {
  position: absolute;
  top: 0;
  left: 0;
}
</style>

 

标签:vue,end,自定义,虚拟化,dataList,start,remain,return,size
来源: https://www.cnblogs.com/lijun12138/p/16631889.html