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 this关键字的问题
Jan 09 Javascript
用jscript启动sqlserver
Jun 21 Javascript
JQuery 学习笔记 选择器之六
Jul 23 Javascript
JQueryEasyUI datagrid框架的进阶使用
Apr 08 Javascript
浅谈JavaScript异常处理语句
Jun 26 Javascript
MVC Ajax Helper或Jquery异步加载部分视图
Nov 29 Javascript
jQuery禁用键盘后退屏蔽F5刷新及禁用右键单击
Jan 22 Javascript
jquery删除数组中重复元素
Dec 05 Javascript
jQuery操作复选框(CheckBox)的取值赋值实现代码
Jan 10 Javascript
js is_valid_filename验证文件名的函数
Jul 19 Javascript
Vue 过滤器filters及基本用法
Dec 26 Javascript
jquery 获取索引值在一定范围的列表方法
Jan 25 jQuery
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仿盗链代码
2012/06/03 PHP
PHP获取文件的MD5值并判断是否被修改的例子
2014/06/19 PHP
Yii2中如何使用modal弹窗(基本使用)
2016/05/30 PHP
[企业公众号]升级到[企业微信]之后发送消息失败的解决方法
2017/06/30 PHP
ecshop添加菜单及权限分配问题
2017/11/21 PHP
PHP封装mysqli基于面向对象的mysql数据库操作类与用法示例
2019/02/25 PHP
js几个不错的函数 $$()
2006/10/09 Javascript
一个css与js结合的下拉菜单支持主流浏览器
2014/10/08 Javascript
解析JavaScript面向对象概念中的Object类型与作用域
2016/05/10 Javascript
使用JavaScript获取URL中的参数(两种方法)
2016/11/16 Javascript
简单谈谈React中的路由系统
2017/07/25 Javascript
Vue v2.5 调整和更新不完全问题
2017/10/24 Javascript
详解vue添加删除元素的方法
2018/06/30 Javascript
Vue 解决多级动态面包屑导航的问题
2019/11/04 Javascript
AI小程序之语音听写来了,十分钟掌握百度大脑语音听写全攻略
2020/03/13 Javascript
js实现金山打字通小游戏
2020/07/24 Javascript
python中使用enumerate函数遍历元素实例
2014/06/16 Python
Python多进程机制实例详解
2015/07/02 Python
python3.0 模拟用户登录,三次错误锁定的实例
2017/11/02 Python
Python图像的增强处理操作示例【基于ImageEnhance类】
2019/01/03 Python
python的依赖管理的实现
2019/05/14 Python
Python八皇后问题解答过程详解
2019/07/29 Python
python实现跨excel sheet复制代码实例
2020/03/03 Python
numpy 矩阵形状调整:拉伸、变成一位数组的实例
2020/06/18 Python
CSS3混合模式mix-blend-mode/background-blend-mode简介
2018/03/15 HTML / CSS
CSS3实现王者荣耀匹配人员加载页面的方法
2019/04/16 HTML / CSS
HTML5之HTML元素扩展(下)—增强的Form表单元素值得关注
2013/01/31 HTML / CSS
New Balance波兰官方商城:始于1906年,百年慢跑品牌
2017/08/15 全球购物
世界顶级足球门票网站:Live Football Tickets
2017/10/14 全球购物
为什么Runtime.exec(“ls”)没有任何输出?
2014/10/03 面试题
小学教师岗位职责
2013/11/25 职场文书
《草原的早晨》教学反思
2014/04/08 职场文书
英语系本科生求职信
2014/07/15 职场文书
学生夜不归宿检讨书
2014/09/23 职场文书
HAM-2000摩机图
2021/04/22 无线电
HTML5页面打开微信小程序功能实现
2022/09/23 HTML / CSS