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 相关文章推荐
基于jquery的划词搜索实现(备忘)
Sep 14 Javascript
通过Javascript创建一个选择文件的对话框代码
Jun 16 Javascript
js 判断上传文件大小及格式代码
Nov 13 Javascript
JavaScript数据结构与算法之链表
Jan 29 Javascript
JavaScript模拟数组合并concat
Mar 06 Javascript
IE和Firefox之间在JavaScript语法上的差异
Apr 22 Javascript
Vue使用vue-cli创建项目
Sep 01 Javascript
微信小程序 上传头像的实例详解
Oct 27 Javascript
解决axios发送post请求返回400状态码的问题
Aug 11 Javascript
node中使用es6/7/8(支持性与性能)
Mar 28 Javascript
javascript利用canvas实现鼠标拖拽功能
Jul 23 Javascript
Element PageHeader页头的使用方法
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
六酷社区论坛HOME页清新格调免费版 下载
2007/03/07 PHP
php smarty的预保留变量总结
2008/12/04 PHP
详细解读PHP中接口的应用
2015/08/12 PHP
thinkphp5实现无限级分类
2019/02/18 PHP
javawscript 三级菜单的实现原理
2009/07/01 Javascript
jQuery ui 1.7更新小结
2009/08/15 Javascript
ASP.NET jQuery 实例11 通过使用jQuery validation插件简单实现用户登录页面验证功能
2012/02/03 Javascript
php is_numberic函数造成的SQL注入漏洞
2014/03/10 Javascript
Javascript闭包(Closure)详解
2015/05/05 Javascript
快速掌握Node.js模块封装及使用
2016/03/21 Javascript
使用jQuery判断浏览器滚动条位置的方法
2016/05/30 Javascript
AngularJS 限定$scope的范围实例详解
2017/06/23 Javascript
基于zepto.js实现登录界面
2017/10/09 Javascript
深入浅析vue组件间事件传递
2017/12/29 Javascript
python list 合并连接字符串的方法
2013/03/09 Python
Python简单实现TCP包发送十六进制数据的方法
2016/04/16 Python
python实现字符串连接的三种方法及其效率、适用场景详解
2017/01/13 Python
Python实现图片转字符画的示例
2017/08/22 Python
python处理Excel xlrd的简单使用
2017/09/12 Python
python中lambda()的用法
2017/11/16 Python
Python使用matplotlib绘制随机漫步图
2018/08/27 Python
Python中按键来获取指定的值
2019/03/02 Python
OpenCV-Python 摄像头实时检测人脸代码实例
2019/04/30 Python
Python机器学习算法库scikit-learn学习之决策树实现方法详解
2019/07/04 Python
python 3.7.4 安装 opencv的教程
2019/10/10 Python
python调用Matplotlib绘制分布点图
2019/10/18 Python
Python openpyxl 插入折线图实例
2020/04/17 Python
Keras 切换后端方式(Theano和TensorFlow)
2020/06/19 Python
浅谈如何使用python抓取网页中的动态数据实现
2020/08/17 Python
Pycharm安装第三方库失败解决方案
2020/11/17 Python
使用CSS3的ruby-position固定注音位置的用法示例
2016/07/05 HTML / CSS
家用个人磨皮机:Trophy Skin
2017/03/30 全球购物
亚洲独特体验旅游专家:eOasia
2018/08/15 全球购物
在C#中如何实现多态
2014/07/02 面试题
调研汇报材料范文
2014/08/17 职场文书
创业计划书之o2o水果店
2019/08/30 职场文书