vue实现虚拟列表功能的代码


Posted in Javascript onJuly 28, 2020

当数据量较大(此处设定为10w),而且要用列表的形式展现给用户,如果我们不做处理的话,在浏览器中渲染10w dom节点,是极其耗费时间的,那我的Macbook air举例,10w条数据渲染出来到能看到页面,需要13秒多(实际应该是10秒左右),如果是用户的话肯定是不会等一个网页十几秒的

vue实现虚拟列表功能的代码

我们可以用虚拟列表解决这个问题
一步步来
首先看一下效果

vue实现虚拟列表功能的代码

这是data中的数据

data() {
  return {
   list: [], // 贼大的数组
   li: {
    // 列表项信息
    height: 50,
   },
   container: {
    // 容器信息
    height: 500,
   },
   pos: 1, // 第一排显示的元素的下标
   MAX_NUM: 1, // 在容器内最多显示几个列表项
   timer: null, // 定时器
   carriedOut: true, // 能不能执行操作
  };
 },

然后在mounted中创建一个贼大的数组,在调用test方法计算第一次的虚拟列表中有哪些

mounted() {
  // 创建一个贼大的数据数组
  for (let i = 0; i < 100000; i++) {
   this.list.push(i);
  }
  this.test();
 },

test方法

test() {
   // 节流
   if (this.carriedOut) {
    // 容器跟里面的列表项
    const { container, li } = this;
    // 计算可视区域最多能显示多少个li
    this.MAX_NUM = Math.ceil(container.height / li.height);
    // 获取 overflow:scroll 的元素已滚动的高度
    let scrollTop = this.$refs.container.scrollTop;
    // 计算当前处于第一排的元素的下标
    this.pos = Math.round(scrollTop / li.height);
    // 下方节流操作
    this.carriedOut = false;
    this.timer = setTimeout(() => {
     this.carriedOut = true;
     clearTimeout(this.timer);
    }, 50);
   }
  },

然后是computed

computed: {
  // 用于渲染在页面上的数组
  showList() {
   // 根据计算出来的 第一排元素的下标,和最多显示多少个 用slice实现截取数组
   let arr = this.list.slice(this.pos, this.pos + this.MAX_NUM);
   return arr;
  },
 },

这是html,注意监听了div的scroll事件,并且调用的是test方法

<div class="virtual-list">
  <h1>虚拟列表</h1>
  <div class="container" ref="container" :style="`height:${container.height}px`" @scroll="test">
   <ul :style="`height:${li.height*list.length}px;padding-top:${li.height*pos}px`">
    <li :style="`height:${li.height}px`" v-for="item in 100000" :key="item">{{item}}</li>
   </ul>
  </div>
 </div>

完整源代码

<template>
 <div class="virtual-list">
  <h1>虚拟列表</h1>
  <div class="container" ref="container" :style="`height:${container.height}px`" @scroll="test">
   <ul :style="`height:${li.height*list.length}px;padding-top:${li.height*pos}px`">
    <li :style="`height:${li.height}px`" v-for="item of showList" :key="item">{{item}}</li>
   </ul>
  </div>
 </div>
</template>

<script>
export default {
 data() {
  return {
   list: [], // 贼大的数组
   li: {
    // 列表项信息
    height: 50,
   },
   container: {
    // 容器信息
    height: 500,
   },
   pos: 1, // 第一排显示的元素的下标
   MAX_NUM: 1, // 在容器内最多显示几个列表项
   timer: null, // 定时器
   carriedOut: true, // 能不能执行操作
  };
 },
 mounted() {
  // 创建一个贼大的数据数组
  for (let i = 0; i < 1000; i++) {
   this.list.push(i);
  }
  this.test();
 },
 computed: {
  // 用于渲染在页面上的数组
  showList() {
   // 根据计算出来的 第一排元素的下标,和最多显示多少个 用slice实现截取数组
   let arr = this.list.slice(this.pos, this.pos + this.MAX_NUM);
   return arr;
  },
 },
 methods: {
  test() {
   // 节流
   if (this.carriedOut) {
    // 容器跟里面的列表项
    const { container, li } = this;
    // 计算可视区域最多能显示多少个li
    this.MAX_NUM = Math.ceil(container.height / li.height);
    // 获取 overflow:scroll 的元素已滚动的高度
    let scrollTop = this.$refs.container.scrollTop;
    // 计算当前处于第一排的元素的下标
    this.pos = Math.round(scrollTop / li.height);
    // 下方节流操作
    this.carriedOut = false;
    this.timer = setTimeout(() => {
     this.carriedOut = true;
     clearTimeout(this.timer);
    }, 50);
   }
  },
 },
};
</script>

<style lang="scss" scoped>
.virtual-list {
 text-align: center;
 .container {
  overflow: scroll;
  border: 1px solid red;
 }
}
</style>

到此这篇关于vue实现虚拟列表功能的代码的文章就介绍到这了,更多相关vue 虚拟列表内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
javascript 表单的友好用户体现
Jan 07 Javascript
javascript常用对话框小集
Sep 13 Javascript
JS控制一个DIV层在指定时间内消失的方法
Feb 17 Javascript
javascript 模拟坦克大战游戏(html5版)附源码下载
Apr 08 Javascript
IE8中动态创建script标签onload无效的解决方法
Dec 22 Javascript
Node.js node-schedule定时任务隔多少分钟执行一次的方法
Feb 10 Javascript
jQuery 的 ready()的纯js替代方法
Nov 20 Javascript
vue.js入门(3)——详解组件通信
Dec 02 Javascript
JavaScript调试的多个必备小Tips
Jan 15 Javascript
Centos6.8下Node.js安装教程
May 12 Javascript
浅谈webpack和webpack-cli模块源码分析
Jan 19 Javascript
vue项目实现多语言切换的思路
Sep 17 Javascript
vue.js 解决v-model让select默认选中不生效的问题
Jul 28 #Javascript
Vue2.0 $set()的正确使用详解
Jul 28 #Javascript
JavaScript 监听组合按键思路及代码实现
Jul 28 #Javascript
JavaScript动画实例之粒子文本的实现方法详解
Jul 28 #Javascript
Vue $emit()不能触发父组件方法的原因及解决
Jul 28 #Javascript
vue 遮罩层阻止默认滚动事件操作
Jul 28 #Javascript
JavaScript实现沿五角星形线摆动的小圆实例详解
Jul 28 #Javascript
You might like
第十一节--重载
2006/11/16 PHP
php图片加水印原理(超简单的实例代码)
2013/01/18 PHP
Firefox/Chrome/Safari的中可直接使用$/$$函数进行调试
2012/02/13 Javascript
Node.js重新刷新session过期时间的方法
2016/02/04 Javascript
BootStrap Typeahead自动补全插件实例代码
2016/08/10 Javascript
Bootstrap Table使用方法解析
2016/10/19 Javascript
nodejs redis 发布订阅机制封装实现方法及实例代码
2016/12/15 NodeJs
angularjs中ng-bind-html的用法总结
2017/05/23 Javascript
详解Vue.js基于$.ajax获取数据并与组件的data绑定
2017/05/26 Javascript
vue项目中使用axios上传图片等文件操作
2017/11/02 Javascript
vue checkbox 全选 数据的绑定及获取和计算方法
2018/02/09 Javascript
使用Angular CLI快速创建Angular项目的一些基本概念和写法小结
2018/04/22 Javascript
详解Angular中通过$location获取地址栏的参数
2018/08/02 Javascript
Vue触发式全局组件构建的方法
2018/11/28 Javascript
vue滚动固定顶部及修改样式的实例代码
2019/05/30 Javascript
js实现日历
2020/11/07 Javascript
python3+PyQt5实现使用剪贴板做复制与粘帖示例
2017/01/24 Python
Python输出各行命令详解
2018/02/01 Python
Python中format()格式输出全解
2019/04/12 Python
10个Python面试常问的问题(小结)
2019/11/20 Python
哈利波特商店:Harry Potter Shop
2018/11/30 全球购物
绢花、人造花和人造花卉:BLOOM
2019/08/07 全球购物
说一下Linux下有关用户和组管理的命令
2016/01/04 面试题
Lucene推荐的分页方式是什么?
2015/12/07 面试题
十佳大学生村官事迹
2014/01/09 职场文书
心理健康教育制度
2014/01/27 职场文书
小区停车场管理制度
2014/01/27 职场文书
大学班级学风建设方案
2014/05/01 职场文书
学术诚信承诺书
2014/05/26 职场文书
要账委托书范本
2014/09/15 职场文书
村长党的群众路线教育实践活动个人对照检查材料
2014/09/23 职场文书
劳动纠纷调解协议书格式
2014/11/30 职场文书
质量保证书
2015/01/17 职场文书
爱心捐款感谢信
2015/01/20 职场文书
2015年房产销售工作总结范文
2015/05/22 职场文书
2016应届毕业生自荐信范文
2016/01/28 职场文书