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生成asp.net服务器控件的代码
Feb 04 Javascript
jquery入门—编写一个导航条(可伸缩)
Jan 07 Javascript
extjs tabpanel限制选项卡数量实现思路及代码
Apr 02 Javascript
js 限制input只能输入数字、字母和汉字等等
Dec 18 Javascript
JS比较两个时间大小的简单示例代码
Dec 20 Javascript
原生js获取浏览器窗口及元素宽高常用方法集合
Jan 18 Javascript
Vue 2.0+Vue-router构建一个简单的单页应用(附源码)
Mar 14 Javascript
get  post jsonp三种数据交互形式实例详解
Aug 25 Javascript
Web开发使用Angular实现用户密码强度判别的方法
Sep 27 Javascript
elementUI Vue 单个按钮显示和隐藏的变换功能(两种方法)
Sep 04 Javascript
深入webpack打包原理及loader和plugin的实现
May 06 Javascript
javaScript代码飘红报错看不懂?读完这篇文章再试试
Aug 19 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
山进SANGEAN ATS-909X电路分析
2021/03/02 无线电
php在服务器执行exec命令失败的解决方法
2012/03/03 PHP
PHPMailer的主要功能特点和简单使用说明
2014/02/17 PHP
10个实用的PHP正则表达式汇总
2014/10/23 PHP
总结PHP如何获取当前主机、域名、网址、路径、端口和参数等
2016/09/09 PHP
PHP实现将几张照片拼接到一起的合成图片功能【便于整体打印输出】
2017/11/14 PHP
PHP面向对象五大原则之单一职责原则(SRP)详解
2018/04/04 PHP
PHP后台实现微信小程序登录
2018/08/03 PHP
PHPstorm启用自动换行的方法详解(IDE)
2020/09/17 PHP
javascript确认框的三种使用方法
2013/12/17 Javascript
javascript格式化日期时间方法汇总
2015/06/19 Javascript
JS实现n秒后自动跳转的两种方法
2020/11/30 Javascript
AngularJS ng-bind 指令简单实现
2016/07/30 Javascript
vue.js国际化 vue-i18n插件的使用详解
2017/07/07 Javascript
AngularJS service之select下拉菜单效果
2017/07/28 Javascript
基于JavaScript中标识符的命名规则介绍
2018/01/06 Javascript
security.js实现的RSA加密功能示例
2018/06/06 Javascript
微信小程序自定义弹窗滚动与页面滚动冲突的解决方法
2019/07/16 Javascript
基于jQuery实现可编辑的表格
2019/12/11 jQuery
OpenLayers3实现地图鹰眼以及地图比例尺的添加
2020/09/25 Javascript
node使用async_hooks模块进行请求追踪
2021/01/28 Javascript
python 解析html之BeautifulSoup
2009/07/07 Python
在Django框架中编写Contact表单的教程
2015/07/17 Python
在Windows中设置Python环境变量的实例讲解
2018/04/28 Python
Redis使用watch完成秒杀抢购功能的代码
2018/05/07 Python
Python socket实现多对多全双工通信的方法
2019/02/13 Python
Python selenium文件上传下载功能代码实例
2020/04/13 Python
俄罗斯皮肤健康中心:Pharmacosmetica.ru
2020/02/22 全球购物
Linux管理员面试题 Linux admin interview questions
2014/11/01 面试题
优秀生推荐信范文
2013/11/28 职场文书
冰淇淋开店创业计划书
2014/02/01 职场文书
交通安全寄语大全
2014/04/08 职场文书
保密工作整改情况汇报
2014/11/06 职场文书
2014年小学数学教师工作总结
2014/12/03 职场文书
医院病假条怎么写
2015/08/17 职场文书
评测 | 大屏显示带收音机的高端音箱,JBL TUNE2便携式插卡音箱实测
2021/04/24 无线电