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 replace 字符替换实现代码
Dec 02 Javascript
JS实现图片翻书效果示例代码
Sep 09 Javascript
jqplot通过ajax动态画折线图的方法及思路
Dec 08 Javascript
代码获取历史上的今天发生的事
Apr 11 Javascript
jquery实现平滑的二级下拉菜单效果
Aug 26 Javascript
JQuery操作textarea,input,select,checkbox方法
Sep 02 Javascript
javascript图片切换综合实例(循环切换、顺序切换)
Jan 13 Javascript
JavaScript判断数组是否存在key的简单实例
Aug 03 Javascript
关于foreach循环中遇到的问题小结
May 08 Javascript
详解Angular 中 ngOnInit 和 constructor 使用场景
Jun 22 Javascript
vue项目从node8.x升级到12.x后的问题解决
Oct 25 Javascript
React更新渲染原理深入分析
Dec 24 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反弹shell实现代码
2009/04/22 PHP
PHP连接MYSQL数据库实例代码
2016/01/20 PHP
php 7新特性之类型申明详解
2017/06/06 PHP
php框架知识点的整理和补充
2021/03/01 PHP
使用onbeforeunload属性后的副作用
2007/03/08 Javascript
javascript parseInt 大改造
2009/09/27 Javascript
JQuery 获取和设置Select选项的代码
2010/02/07 Javascript
jQuery(非HTML5)可编辑表格实现代码
2012/12/11 Javascript
Jquery焦点图实例代码
2014/11/25 Javascript
JavaScript实现16进制颜色值转RGB的方法
2015/02/09 Javascript
浅谈JavaScript中的Math.atan()方法的使用
2015/06/14 Javascript
深入浅析JavaScript字符串操作方法 slice、substr、substring及其IE兼容性
2015/12/16 Javascript
探索angularjs+requirejs全面实现按需加载的套路
2016/02/26 Javascript
Angularjs CURD 详解及实例代码
2016/09/14 Javascript
JS封装的三级联动菜单(使用时只需要一行js代码)
2016/10/24 Javascript
jQuery基于cookie实现换肤功能实例
2017/10/14 jQuery
微信小程序实现笑脸评分功能
2018/11/03 Javascript
nodejs和react实现即时通讯简易聊天室功能
2019/08/21 NodeJs
vue和iview实现Scroll 数据无限滚动功能
2019/10/31 Javascript
Vue 解决多级动态面包屑导航的问题
2019/11/04 Javascript
vue element 中的table动态渲染实现(动态表头)
2019/11/21 Javascript
JS运算符简单用法示例
2020/01/19 Javascript
[40:55]Liquid vs LGD 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
wxpython中利用线程防止假死的实现方法
2014/08/11 Python
Python tkinter实现的图片移动碰撞动画效果【附源码下载】
2018/01/04 Python
使用python和Django完成博客数据库的迁移方法
2018/01/05 Python
Python数据类型之Tuple元组实例详解
2019/05/08 Python
Python传递参数的多种方式(小结)
2019/09/18 Python
加拿大鞋网:Globo Shoes
2019/12/26 全球购物
母亲追悼会答谢词
2014/01/27 职场文书
关于抽烟的检讨书
2014/02/25 职场文书
地方白酒代理协议书
2014/10/25 职场文书
学生个人总结范文
2015/02/15 职场文书
志愿者服务活动总结报告
2015/05/06 职场文书
商业计划书格式、范文
2019/03/21 职场文书
MYSQL 无法识别中文的永久解决方法
2021/06/03 MySQL