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 相关文章推荐
JavaScript操作XML实例代码(获取新闻标题并分页,并分页)
May 25 Javascript
jQuery实现自定义事件的方法
Apr 17 Javascript
ui组件之input多选下拉实现方法(带有搜索功能)
Jul 14 Javascript
JS获取IE版本号与HTML设置IE文档模式的方法
Oct 09 Javascript
无法获取隐藏元素宽度和高度的解决方案
Mar 07 Javascript
vue如何实现observer和watcher源码解析
Mar 09 Javascript
JScript实现地址选择功能
Aug 15 Javascript
微信小程序实现鼠标拖动效果示例
Dec 01 Javascript
深入浅出vue图片路径的实现
Sep 04 Javascript
vue 实现锚点功能操作
Aug 10 Javascript
Vue基于localStorage存储信息代码实例
Nov 16 Javascript
vue的hash值原理也是table切换实例代码
Dec 14 Vue.js
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
B2K与车机的中波PK
2021/03/02 无线电
用PHP和ACCESS写聊天室(五)
2006/10/09 PHP
织梦模板标记简介
2007/03/11 PHP
php环境配置 php5 MySQL5 apache2 phpmyadmin安装与配置图文教程
2007/03/16 PHP
Blitz templates 最快的PHP模板引擎
2010/04/06 PHP
PHP 自定义错误处理函数trigger_error()
2013/03/26 PHP
win7系统配置php+Apache+mysql环境的方法
2015/08/21 PHP
Zend Framework动作助手Url用法详解
2016/03/05 PHP
PHP的Yii框架中移除组件所绑定的行为的方法
2016/03/18 PHP
用jscript实现新建和保存一个word文档
2007/06/15 Javascript
JavaScript开发时的五个注意事项
2007/12/08 Javascript
基于jquery的图片懒加载js
2010/06/30 Javascript
JavaScript插件化开发教程 (一)
2015/01/27 Javascript
JavaScript检测字符串中是否含有html标签实现方法
2015/07/01 Javascript
js+div实现文字滚动和图片切换效果代码
2015/08/27 Javascript
AngularJS优雅的自定义指令
2016/07/01 Javascript
jQuery时间日期三级联动(推荐)
2016/11/27 Javascript
Angular2使用Angular CLI快速搭建工程(一)
2017/05/21 Javascript
基于 webpack2 实现的多入口项目脚手架详解
2017/06/26 Javascript
vue 监听键盘回车事件详解 @keyup.enter || @keyup.enter.native
2018/08/25 Javascript
jQuery实现鼠标移入移出事件切换功能示例
2018/09/06 jQuery
layui自定义ajax左侧三级菜单
2019/07/26 Javascript
基于JavaScript实现简单扫雷游戏
2021/01/02 Javascript
Python中使用Tkinter模块创建GUI程序实例
2015/01/14 Python
Python中标准模块importlib详解
2017/04/16 Python
浅谈Python黑帽子取代netcat
2018/02/10 Python
Python+OpenCV采集本地摄像头的视频
2019/04/25 Python
Python一行代码实现快速排序的方法
2019/04/30 Python
在Qt中正确的设置窗体的背景图片的几种方法总结
2019/06/19 Python
opencv转换颜色空间更改图片背景
2019/08/20 Python
pycharm 2018 激活码及破解补丁激活方式
2020/09/21 Python
Django windows使用Apache实现部署流程解析
2020/10/12 Python
2014党的群众路线教育实践活动学习心得体会
2014/10/31 职场文书
毕业生就业推荐表自我鉴定
2019/06/20 职场文书
Vue通过懒加载提升页面响应速度
2021/05/10 Vue.js
python和C/C++混合编程之使用ctypes调用 C/C++的dll
2022/04/29 Python