ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

vue自定义实现虚拟化列表

2022-08-28 01:33:00  阅读:175  来源: 互联网

标签:vue end 自定义 虚拟化 dataList start remain return size


 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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有