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 二维数组的实现与应用
Mar 16 Javascript
JS弹出对话框返回值代码(asp.net后台)
Dec 28 Javascript
JS对外部文件的加载及对IFRMAME的加载的实现,当加载完成后,指定指向方法(方法回调)
Jul 04 Javascript
使用jQuery.wechat构建微信WEB应用
Oct 09 Javascript
js判断checkbox是否选中个数的方法(超简单)
Aug 19 Javascript
javascript工厂模式和构造函数模式创建对象方法解析
Dec 30 Javascript
详解AngularJs HTTP响应拦截器实现登陆、权限校验
Apr 11 Javascript
vue 实现走马灯效果
Oct 28 Javascript
关于vue路由缓存清除在main.js中的设置
Nov 06 Javascript
JS实现电商商品展示放大镜特效
Jan 07 Javascript
浅谈javascript事件环微任务和宏任务队列原理
Sep 12 Javascript
Vue实现开关按钮拖拽效果
Sep 22 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
thinkphp项目如何自定义微信分享描述内容
2017/02/20 PHP
二行代码解决全部网页木马
2008/03/28 Javascript
在JS中最常看到切最容易迷惑的语法(转)
2010/10/29 Javascript
父子窗体间传递JSON格式的数据的代码
2010/12/25 Javascript
javascript中[]和{}对象使用介绍
2013/03/20 Javascript
jquery遍历select元素(实例讲解)
2013/12/31 Javascript
鼠标滑过出现预览的大图提示效果
2014/02/26 Javascript
jquery库或JS文件在eclipse下报错问题解决方法
2014/04/17 Javascript
谈谈JavaScript中的几种借用方法
2016/08/09 Javascript
JavaScript自定义浏览器滚动条兼容IE、 火狐和chrome
2017/01/05 Javascript
AngularJs+Bootstrap实现漂亮的计算器
2017/08/10 Javascript
react 父子组件之间通讯props
2018/09/08 Javascript
利用Vconsole和Fillder进行移动端抓包调试方法
2019/03/05 Javascript
mpvue小程序循环动画开启暂停的实现方法
2019/05/15 Javascript
python通过urllib2爬网页上种子下载示例
2014/02/24 Python
django自定义Field实现一个字段存储以逗号分隔的字符串
2014/04/27 Python
Django静态资源URL STATIC_ROOT的配置方法
2014/11/08 Python
Python socket实现的简单通信功能示例
2018/08/21 Python
python3+pyqt5+itchat微信定时发送消息的方法
2019/02/20 Python
Python获取数据库数据并保存在excel表格中的方法
2019/06/12 Python
Python中栈、队列与优先级队列的实现方法
2019/06/30 Python
python查看数据类型的方法
2019/10/12 Python
python DES加密与解密及hex输出和bs64格式输出的实现代码
2020/04/13 Python
美国指甲油品牌:Deco Miami
2017/01/30 全球购物
Subside Sports德国:足球球衣和球迷商品
2019/06/08 全球购物
澳大利亚最大的护发和护肤品购物网站:RY
2019/12/26 全球购物
应届生高等护理求职信
2013/10/12 职场文书
求职简历中的自我评价分享
2013/12/08 职场文书
初中考试作弊检讨书
2014/02/01 职场文书
怎样填写就业意向
2014/04/02 职场文书
施工安全标语
2014/06/07 职场文书
2014年幼儿园国庆主题活动方案
2014/09/16 职场文书
计算机实训报告范文
2014/11/05 职场文书
2014年办公室文员工作总结
2014/11/12 职场文书
三好学生事迹材料
2014/12/24 职场文书
车辆安全隐患排查制度
2015/08/05 职场文书