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 相关文章推荐
解决Extjs 4 Panel作为Window组件的子组件时出现双重边框问题
Jan 11 Javascript
Extjs Label的 fieldLabel和html属性值对齐的方法
Jun 15 Javascript
jquery操作 iframe的方法
Dec 03 Javascript
Javascript基础教程之if条件语句
Jan 18 Javascript
JavaScript中的small()方法使用详解
Jun 08 Javascript
详解JavaScript中shift()方法的使用
Jun 09 Javascript
在JavaScript中访问字符串的子串
Jul 07 Javascript
JavaScript预解析及相关技巧分析
Apr 21 Javascript
Vue.js 插件开发详解
Mar 29 Javascript
JavaScript创建对象_动力节点Java学院整理
Jun 27 Javascript
javascript将非数值转换为数值
Sep 13 Javascript
JS实现从对象获取对象中单个键值的方法示例
Jun 05 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连接access数据库
2008/03/27 PHP
Ajax PHP简单入门教程代码
2008/04/25 PHP
php Session存储到Redis的方法
2013/11/04 PHP
php时区转换转换函数
2014/01/07 PHP
PHP JSON出错:Cannot use object of type stdClass as array解决方法
2014/08/16 PHP
Yii2选项卡的简单使用
2017/05/26 PHP
PHP实现的堆排序算法详解
2017/08/17 PHP
PHP排序算法之快速排序(Quick Sort)及其优化算法详解
2018/04/21 PHP
jquery与prototype框架的详细对比
2013/11/21 Javascript
jQuery选择器源码解读(四):tokenize方法的Expr.preFilter
2015/03/31 Javascript
jQuery网页右侧广告跟随滚动代码分享
2020/04/20 Javascript
jQuery简单实现点击文本框复制内容到剪贴板上的方法
2016/08/01 Javascript
浅谈javascript中的三种弹窗
2016/10/21 Javascript
JavaScript利用闭包实现模块化
2017/01/13 Javascript
Nodejs之http的表单提交
2017/07/07 NodeJs
Angular.js前台传list数组由后台spring MVC接收数组示例代码
2017/07/31 Javascript
关于redux-saga中take使用方法详解
2018/02/27 Javascript
JS中this的指向以及call、apply的作用
2018/05/06 Javascript
JS立即执行函数功能与用法分析
2019/01/15 Javascript
使用vue-cli3+typescript的项目模板创建工程的教程
2020/02/28 Javascript
vue项目接口管理,所有接口都在apis文件夹中统一管理操作
2020/08/13 Javascript
利用Python开发实现简单的记事本
2016/11/15 Python
解决新版Pycharm中Matplotlib图像不在弹出独立的显示窗口问题
2019/01/15 Python
Python实现使用request模块下载图片demo示例
2019/05/24 Python
python matplotlib包图像配色方案分享
2020/03/14 Python
Python如何截图保存的三种方法(小结)
2020/09/01 Python
大专生工程监理求职信
2013/10/04 职场文书
消防战士优秀事迹材料
2014/02/13 职场文书
普通简短的个人自我评价
2014/02/15 职场文书
党员演讲稿
2014/09/04 职场文书
2014年党建工作汇报材料
2014/10/27 职场文书
员工自我评价范文
2015/03/11 职场文书
死者家属慰问信
2015/03/24 职场文书
长征观后感
2015/06/09 职场文书
Nginx缓存设置案例详解
2021/09/15 Servers
利用 Python 的 Pandas和 NumPy 库来清理数据
2022/04/13 Python