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高级学习笔记整理
Aug 14 Javascript
ie6下png图片背景不透明的解决办法使用js实现
Jan 11 Javascript
使用focus方法让光标默认停留在INPUT框
Jul 29 Javascript
javascript实现window.print()去除页眉页脚
Dec 30 Javascript
用JS动态改变表单form里的action值属性的两种方法
May 25 Javascript
修改js confirm alert 提示框文字的简单实例
Jun 10 Javascript
javascript基于原型链的继承及call和apply函数用法分析
Dec 15 Javascript
深入理解JavaScript中的预解析
Jan 04 Javascript
js字符串处理之绝妙的代码
Apr 05 Javascript
微信小程序拼接图片链接无底洞深入探究
Sep 03 Javascript
webpack4 配置 ssr 环境遇到“document is not defined”
Oct 24 Javascript
vue如何清除浏览器历史栈
May 25 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
PHP实现阳历到农历转换的类实例
2015/03/07 PHP
利用 fsockopen() 函数开放端口扫描器的实例
2017/08/19 PHP
JS中获取数据库中的值的方法
2013/07/14 Javascript
javascript不同类型数据之间的运算的转换方法
2014/02/13 Javascript
jquery实现多屏多图焦点图切换特效的方法
2015/05/04 Javascript
Javascript中String的常用方法实例分析
2015/06/13 Javascript
js实现显示当前状态的导航效果代码
2015/08/28 Javascript
JavaScript实现仿新浪微博大厅和腾讯微博首页滚动特效源码
2015/09/15 Javascript
JS实现的鼠标跟随代码(卡通手型点击效果)
2015/10/26 Javascript
jquery获取easyui日期控件的值实现方法
2016/11/09 Javascript
angularjs中ng-attr的用法详解
2016/12/31 Javascript
bootstrap table配置参数例子
2017/01/05 Javascript
原生JS改变透明度实现轮播效果
2017/03/24 Javascript
Vue中的v-cloak使用解读
2017/03/27 Javascript
NodeJS测试框架mocha入门教程
2017/03/28 NodeJs
ES6新特性四:变量的解构赋值实例
2017/04/21 Javascript
vue自定义底部导航栏Tabbar的实现代码
2018/09/03 Javascript
python判断端口是否打开的实现代码
2013/02/10 Python
详解Python list 与 NumPy.ndarry 切片之间的对比
2017/07/24 Python
tensorflow获取变量维度信息
2018/03/10 Python
sublime python3 输入换行不结束的方法
2018/04/19 Python
python实现点击按钮修改数据的方法
2019/07/17 Python
详解Python list和numpy array的存储和读取方法
2019/11/06 Python
python中常见错误及解决方法
2020/06/21 Python
Python 微信公众号文章爬取的示例代码
2020/11/30 Python
荷兰网上鞋店:Ziengs.nl
2017/01/02 全球购物
戴森比利时官方网站:Dyson BE
2020/10/03 全球购物
怎样创建、运行java程序
2014/08/01 面试题
大学生大二自我鉴定
2013/10/28 职场文书
商务英语应届生自我鉴定
2013/12/08 职场文书
幼儿运动会邀请函
2014/01/17 职场文书
公司承诺书格式范文
2015/04/28 职场文书
2015年监理个人工作总结
2015/05/23 职场文书
办公室规章制度范本
2015/08/04 职场文书
如何搭建 MySQL 高可用高性能集群
2021/06/21 MySQL
常用的文件对应的MIME类型汇总
2022/04/26 HTML / CSS