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 相关文章推荐
深入理解JS中的变量及作用域、undefined与null
Mar 04 Javascript
你所不了解的javascript操作DOM的细节知识点(一)
Jun 17 Javascript
Vue.js动态添加、删除选题的实例代码
Sep 30 Javascript
如何提高数据访问速度
Dec 26 Javascript
js仿iphone秒表功能 计算平均数
Jan 11 Javascript
JS生成一维码(条形码)功能示例
Jan 19 Javascript
基于jQuery实现文字打印动态效果
Apr 21 jQuery
Node.js安装配置图文教程
May 10 Javascript
AngularJs 延时器、计时器实例代码
Sep 16 Javascript
Bootstrap-table自定义可编辑每页显示记录数
Sep 07 Javascript
Vue 全家桶实现移动端酷狗音乐功能
Nov 16 Javascript
layui实现三级导航菜单
Jul 26 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
php 文件夹删除、php清除缓存程序
2009/08/25 PHP
php生成随机密码的几种方法
2011/01/17 PHP
PHP读取ACCESS数据到MYSQL的代码
2011/05/11 PHP
PHP批量删除、清除UTF-8文件BOM头的代码实例
2014/04/14 PHP
PHP实现清除wordpress里恶意代码
2015/10/21 PHP
Zend Framework动作助手Url用法详解
2016/03/05 PHP
PHP遍历目录文件的常用方法小结
2017/02/03 PHP
彻底搞懂JS无缝滚动代码
2007/01/03 Javascript
JavaScript—window对象使用示例
2013/12/09 Javascript
优化Node.js Web应用运行速度的10个技巧
2014/09/03 Javascript
JavaScript操作Cookie详解
2015/02/28 Javascript
jQuery常用知识点总结以及平时封装常用函数
2016/02/23 Javascript
json传值以及ajax接收详解
2016/05/24 Javascript
js实现为a标签添加事件的方法(使用闭包循环)
2016/08/02 Javascript
基于 Vue 实现一个酷炫的 menu插件
2017/11/14 Javascript
你应该了解的JavaScript Array.map()五种用途小结
2018/11/14 Javascript
详解element-ui中form验证杂记
2019/03/04 Javascript
layuiAdmin循环遍历展示商品图片列表的方法
2019/09/16 Javascript
python3+PyQt5实现使用剪贴板做复制与粘帖示例
2017/01/24 Python
python安装cx_Oracle模块常见问题与解决方法
2017/02/21 Python
python和opencv实现抠图
2018/07/18 Python
详解Python字典的操作
2019/03/04 Python
python安装scipy的步骤解析
2019/09/28 Python
pygame实现俄罗斯方块游戏(AI篇2)
2019/10/29 Python
Python 中判断列表是否为空的方法
2019/11/24 Python
Python三元运算与lambda表达式实例解析
2019/11/30 Python
Python调用shell cmd方法代码示例解析
2020/06/18 Python
无需压缩软件,用python帮你操作压缩包
2020/08/17 Python
HTML5资源预加载(Link prefetch)详细介绍(给你的网页加速)
2014/05/07 HTML / CSS
印尼穆斯林时尚购物网站:Hijabenka
2016/12/10 全球购物
《美丽的公鸡》教学反思
2014/02/25 职场文书
我们的节日春节活动方案
2014/08/22 职场文书
公司员工安全协议书
2014/11/21 职场文书
2015年环卫工作总结
2015/04/28 职场文书
护士心得体会范文
2016/01/25 职场文书
Android在Sqlite3中的应用及多线程使用数据库的建议
2022/04/24 Java/Android