温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
  • 忘记密码?
登录注册×
获取短信验证码
其他方式登录
点击 登录注册 即表示同意 《亿速云用户服务条款》
  • 服务器
  • 数据库
  • 开发技术
  • 网络安全
  • 互联网科技
登 录 注册有礼
最新更新 网站标签 地图导航
产品
  • 首页 > 
  • 教程 > 
  • 开发技术 > 
  • vue虚拟列表如何实现

vue虚拟列表如何实现

发布时间:2022-07-02 09:14:43 来源:亿速云 阅读:292 作者:iii 栏目: 开发技术

本篇内容介绍了“vue虚拟列表如何实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

多数据渲染

现在解决多数据渲染,相信大家可能会想到分页,触底加载,懒加载等等,但其实虚拟列表也是多数据高性能加载的一个重要解决方案。

虚拟列表的概念

虚拟滚动,就是根据容器可视区域的列表容积数量,监听用户滑动或滚动事件,动态截取长列表数据中的部分数据渲染到页面上,动态使用空白站位填充容器上下滚动区域内容,模拟实现原生滚动效果

vue虚拟列表如何实现

  • 浏览器渲染===康熙选秀:一次性渲染10000个肯定会使浏览器压力大,造成用户体验差

  • 容器可视区域===选秀大殿:10000个排队去渲染,比如一次渲染10个

  • 上方下方区域===左右偏殿:轮不到你渲染,你就乖乖进空白区待着

实现

基本实现

  • 可视区域的高度

  • 列表项的高度

  • 可视区域能展示的列表项个数 = ~~(可视区域高度 / 列表项高度) + 2

  • 开始索引

  • 结束索引

  • 预加载(防止滚动过快,造成暂时白屏)

  • 根据开始索引和结束索引,截取数据展示在可视区域

  • 滚动节流

  • 上下空白区使用padding实现

  • 滑动到底,再次请求数据并拼接

<template>
  <div @scroll.passive="doScroll" ref="scrollBox">
    <div : >
      <div v-for="item in tempSanxins" :key="item.id">
        <span>{{ item.msg }}</span>
        <img :src="item.src" />
      </div>
    </div>
  </div>
</template>
<script>
import { throttle } from "../../utils/tools";
export default {
  data() {
    return {
      allSanxins: [], // 所有数据
      itemHiehgt: 150, // 列表每一项的宽度
      boxHeight: 0, // 可视区域的高度
      startIndex: 0, // 元素开始索引
    };
  },
  created() {
    // 模拟请求数据
    this.getAllSanxin(30);
  },
  mounted() {
    // 在mounted时获取可视区域的高度
    this.getScrollBoxHeight();
    // 监听屏幕变化以及旋转,都要重新获取可视区域的高度
    window.onresize = this.getScrollBoxHeight;
    window.onorientationchange = this.getScrollBoxHeight;
  },
  methods: {
    getAllSanxin(count) {
      // 模拟获取数据
      const length = this.allSanxins.length;
      for (let i = 0; i < count; i++) {
        this.allSanxins.push({
          id: `sanxin${length + i}`,
          msg: `我是三心${length + i}号`,
          // 这里随便选一张图片就行
          src: require("../../src/asset/images/sanxin.jpg").default,
        });
      }
    },
    // 使用节流,提高性能
    doScroll: throttle(function () {
      // 监听可视区域的滚动事件
      // 公式:~~(滚动的距离 / 列表项 ),就能算出已经滚过了多少个列表项,也就能知道现在的startIndex是多少
      // 例如我滚动条滚过了160px,那么index就是1,因为此时第一个列表项已经被滚上去了,可视区域里的第一项的索引是1
      const index = ~~(this.$refs.scrollBox.scrollTop / this.itemHiehgt);
      if (index === this.startIndex) return;
      this.startIndex = index;
      if (this.startIndex + this.itemNum > this.allSanxins.length - 1) {
        this.getAllSanxin(30);
      }
    }, 200),
    getScrollBoxHeight() {
      // 获取可视区域的高度
      this.boxHeight = this.$refs.scrollBox.clientHeight;
    },
  },
  computed: {
    itemNum() {
      // 可视区域可展示多少个列表项? 计算公式:~~(可视化区域高度 / 列表项高度) + 2
      // ~~是向下取整的运算符,等同于Math.floor(),为什么要 +2 ,是因为可能最上面和最下面的元素都只展示一部分
      return ~~(this.boxHeight / this.itemHiehgt) + 2;
    },
    endIndex() {
      // endIndex的计算公式:(开始索引 + 可视区域可展示多少个列表项 * 2)
      // 比如可视区域可展示8个列表项,startIndex是0的话endIndex就是0 + 8 * 2 = 16,startIndex是1的话endIndex就是1 + 8 * 2 = 17,以此类推
      // 为什么要乘2呢,因为这样的话可以预加载出一页的数据,防止滚动过快,出现暂时白屏现象
      let index = this.startIndex + this.itemNum * 2;
      if (!this.allSanxins[index]) {
         // 到底的情况,比如startIndex是99995,那么endIndex本应该是99995 + 8 * 2 = 10011
        // 但是列表数据总数只有10000条,此时就需要让endIndex = (列表数据长度 - 1)
        index = this.allSanxins.length - 1;
      }
      return index;
    },
    tempSanxins() {
      //   可视区域展示的截取数据,使用了数组的slice方法,不改变原数组又能截取
      let startIndex = 0;
      if (this.startIndex <= this.itemNum) {
        startIndex = 0;
      } else {
        startIndex = this.startIndex + this.itemNum;
      }
      return this.allSanxins.slice(startIndex, this.endIndex + 1);
    },
    blankStyle() {
      // 上下方的空白处使用padding来充当
      let startIndex = 0;
      if (this.startIndex <= this.itemNum) {
        startIndex = 0;
      } else {
        startIndex = this.startIndex - this.itemNum;
      }
      return {
        // 上方空白的高度计算公式:(开始index * 列表项高度)
        // 比如你滚过了3个列表项,那么上方空白区高度就是3 * 150 = 450,这样才能假装10000个数据的滚动状态
        paddingTop: startIndex * this.itemHiehgt + "px",
         // 下方空白的高度计算公式:(总数据的个数 - 结束index - 1) * 列表项高度
        // 例如现在结束index是100,那么下方空白高度就是:(10000 - 100 - 1) * 150 = 1,484,850
        paddingBottom:
          (this.allSanxins.length - this.endIndex - 1) * this.itemHiehgt + "px",
          // 不要忘了加px哦
      };
    },
  },
};
</script>
<style scoped>
.v-scroll {
  height: 100%;
  /* padding-bottom: 500px; */
  overflow: auto;
  .scroll-item {
    height: 148px;
    /* width: 100%; */
    border: 1px solid black;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0 20px;
    img {
      height: 100%;
    }
  }
}
</style>

“vue虚拟列表如何实现”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!

向AI问一下细节
推荐阅读:
  1. Vue中怎么实现列表渲染
  2. 使用 Vue 实现一个虚拟列表的方法

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

vue
  • 上一篇新闻:
    C++ primer顺序容器实例分析
  • 下一篇新闻:
    vue传值的编码和解码怎么实现

猜你喜欢

  • c#临时变量怎样避免内存泄漏
  • c#中何时使用临时变量最佳
  • c#临时变量命名有哪些规范
  • 如何正确管理c#中的临时变量
  • c#临时变量在不同场景下的应用
  • c#中临时变量的作用域如何定义
  • c#临时变量如何提升代码可读性
  • 如何减少c#临时变量的使用错误
  • c#临时变量与永久变量的区别是什么
  • c#中临时变量的生命周期如何管理
最新资讯
  • Privoxy与Ubuntu浏览器的深度集成
  • Ubuntu用户如何优化Privoxy的CPU占用
  • Privoxy在Ubuntu中提升网络隐私的方法
  • Ubuntu中Privoxy的缓存机制分析
  • Privoxy与Ubuntu防火墙的配合使用
  • Ubuntu用户如何调试Privoxy问题
  • Ubuntu系统Privoxy的兼容性测试报告
  • Privoxy如何帮助Ubuntu用户绕过地域限制
  • Ubuntu中Privoxy的透明代理模式
  • Privoxy在Ubuntu中解决HTTPS问题
相关推荐
  • vue如何实现循环滚动列表
  • React虚拟列表的实现方法
  • vue下拉列表怎么实现
  • vue如何实现虚拟滚动
  • Vue中如何实现列表渲染
  • vue怎么实现列表无缝滚动
  • vue怎么实现虚拟滚动
  • 微信小程序如何实现虚拟列表
  • vue怎么实现评论列表
  • vxe-list vue怎么实现下拉框的虚拟列表

相关标签

vue组件 vue3 mpvue vuecli4 vuedraggable vue-cli4 vue.config.js vue路由 vue2.0 vue父子组件 vuejs9 app.vue vuecli3 vuecli vue2.5 vue.set() vue-cli2.x vue-pdf vue.draggable vue.nexttick
AI

深圳坪山网站建设公司seo网站关键词优化手机网站词语优化中小企业网站优化技巧网站导航优化内容黄石网站seo优化推广赣州网站优化关键词昌乐网站关键词优化上海网站优化哪家效果好巴中网站优化找哪家鸡西网站优化seo福田手机网站优化方法a5网站优化始兴网站优化鹤壁网站关键词排名优化洪梅家具网站优化在线推广网站优化技巧介绍龙井网站优化排名黔西网站建设优化方案网站页面制作优化网站优化心得深圳网站排名优化哪家强铜陵网站建设优化营销谷歌网站优化慢怎么回事优化自己的网站枝江seo网站优化网站搜索条优化南陵百度网站优化合肥滨湖区网站关键词优化网站页面有什么优化建议无锡网站排名优化价格香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声卫健委通报少年有偿捐血浆16次猝死汪小菲曝离婚始末何赛飞追着代拍打雅江山火三名扑火人员牺牲系谣言男子被猫抓伤后确诊“猫抓病”周杰伦一审败诉网易中国拥有亿元资产的家庭达13.3万户315晚会后胖东来又人满为患了高校汽车撞人致3死16伤 司机系学生张家界的山上“长”满了韩国人?张立群任西安交通大学校长手机成瘾是影响睡眠质量重要因素网友洛杉矶偶遇贾玲“重生之我在北大当嫡校长”单亲妈妈陷入热恋 14岁儿子报警倪萍分享减重40斤方法杨倩无缘巴黎奥运考生莫言也上北大硕士复试名单了许家印被限制高消费奥巴马现身唐宁街 黑色着装引猜测专访95后高颜值猪保姆男孩8年未见母亲被告知被遗忘七年后宇文玥被薅头发捞上岸郑州一火锅店爆改成麻辣烫店西双版纳热带植物园回应蜉蝣大爆发沉迷短剧的人就像掉进了杀猪盘当地回应沈阳致3死车祸车主疑毒驾开除党籍5年后 原水城县长再被查凯特王妃现身!外出购物视频曝光初中生遭15人围殴自卫刺伤3人判无罪事业单位女子向同事水杯投不明物质男子被流浪猫绊倒 投喂者赔24万外国人感慨凌晨的中国很安全路边卖淀粉肠阿姨主动出示声明书胖东来员工每周单休无小长假王树国卸任西安交大校长 师生送别小米汽车超级工厂正式揭幕黑马情侣提车了妈妈回应孩子在校撞护栏坠楼校方回应护栏损坏小学生课间坠楼房客欠租失踪 房东直发愁专家建议不必谈骨泥色变老人退休金被冒领16年 金额超20万西藏招商引资投资者子女可当地高考特朗普无法缴纳4.54亿美元罚金浙江一高校内汽车冲撞行人 多人受伤

深圳坪山网站建设公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化