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获取url参数的使用扩展实例
Dec 29 Javascript
Node.js中使用Buffer编码、解码二进制数据详解
Aug 16 Javascript
js控制网页前进和后退的方法
Jun 08 Javascript
JS中多步骤多分步的StepJump组件实例详解
Apr 01 Javascript
Angular和百度地图的结合实例代码
Oct 19 Javascript
AngularJS 在同一个界面启动多个ng-app应用模块详解
Dec 20 Javascript
在vue中添加Echarts图表的基本使用教程
Nov 22 Javascript
浅谈Vue-cli 命令行工具分析
Nov 22 Javascript
用vue-cli开发vue时的代理设置方法
Sep 20 Javascript
Vue自定义指令写法与个人理解
Feb 09 Javascript
微信小程序 高德地图路线规划实现过程详解
Aug 05 Javascript
JavaScript执行机制详细介绍
Dec 06 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
虫族 ZERG 概述
2020/03/14 星际争霸
人大复印资料处理程序_查询篇
2006/10/09 PHP
解决php中Cannot send session cache limiter 的问题的方法
2007/04/27 PHP
snoopy PHP版的网络客户端提供本地下载
2008/04/15 PHP
PHP发送短信代码分享
2015/08/11 PHP
gearman管理工具GearmanManager的安装与php使用方法示例
2020/02/27 PHP
jquery tools之tabs 选项卡/页签
2009/07/25 Javascript
jQuery中将函数赋值给变量的调用方法
2012/03/23 Javascript
jQuery操作select的实例代码
2012/06/14 Javascript
jQuery操作表单常用控件方法小结
2015/03/23 Javascript
javascript实现rgb颜色转换成16进制格式
2015/07/10 Javascript
jQuery实现的淡入淡出二级菜单效果代码
2015/09/15 Javascript
javascript和jquery实现用户登录验证
2016/05/04 Javascript
bootstrap基础知识学习笔记
2016/11/02 Javascript
Bootstrap模态窗口源码解析
2017/02/08 Javascript
高效的jQuery代码编写技巧总结
2017/02/22 Javascript
基于bootstrap实现bootstrap中文网巨幕效果
2017/05/02 Javascript
Vue项目webpack打包部署到服务器的实例详解
2017/07/17 Javascript
vue mint-ui学习笔记之picker的使用
2017/10/11 Javascript
vue axios请求超时的正确处理方法
2018/04/02 Javascript
玩转vue的slot内容分发
2018/09/22 Javascript
JS中封装axios来管控api的2种方式
2019/09/11 Javascript
jquery更改元素属性attr()方法操作示例
2020/05/22 jQuery
[02:57]2014DOTA2国际邀请赛 选手辛苦解说更辛苦
2014/07/10 DOTA
[04:02]2014DOTA2国际邀请赛 BBC每日综述中国战队将再度登顶
2014/07/21 DOTA
Python实现读取机器硬件信息的方法示例
2018/06/09 Python
Python实现多条件筛选目标数据功能【测试可用】
2018/06/13 Python
Python基于pyCUDA实现GPU加速并行计算功能入门教程
2018/06/19 Python
Python操作MySQL数据库的两种方式实例分析【pymysql和pandas】
2019/03/18 Python
python3实现elasticsearch批量更新数据
2019/12/03 Python
简述索引存取方法的作用和建立索引的原则
2013/03/26 面试题
什么是聚集索引和非聚集索引
2012/01/17 面试题
大学生求职计划书
2014/04/30 职场文书
初中国旗下的演讲稿
2014/08/28 职场文书
如何用PHP实现多线程编程
2021/05/26 PHP
MySQL普通表如何转换成分区表
2022/05/30 MySQL