我的编程空间,编程开发者的网络收藏夹
学习永远不晚

vue长列表优化之虚拟列表实现过程详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

vue长列表优化之虚拟列表实现过程详解

前言

应用场景:后台一次性发送上千条或更多数据给前台

场景模拟:用户发起一个请求,后台发送了10w条数据

使用虚拟列表之前:前台需要生成10w个dom节点用来渲染页面

使用虚拟列表之后:前台只需要生成少量dom节点(dom节点数量取决于前端视图需要展示的数量),就可以实现对这10w条数据的视图渲染

总之:虚拟列表就是固定dom节点数量,通过修改dom节点的内容而达到不重新增加(或删除)dom节点来实现列表的更新

实现原理

  • 监听页面滚动,获取滚动的高度scrolltop
  • 根据scrolltop,可以知道当前应该展示哪一段数据(即获取要展示数据的index)
  • 根据当前展示的数据在长列表中的index,对列表进行偏移

实现思路是这样的:

设置列表初始值

  1. 需要展示给用户的数量showNum
  2. 列表item的高度itemHeight
  3. 需要展示的第一条数据的下标start
  4. 需要展示的最后一条数据的下标end
  5. 通过start和end已经showNum,我们可以得到需要展示的列表项showList,我们可以通过vue的计算属性来实时获取新的showList

建立列表视图模型

  • 给列表视图设置高度ListWrapHeight
  • 根据itemHeightshowNum,我们可以得到列表总高度ListHeight,我们必须要使得ListHeight高度大于ListWrapHeight,这样才能实现滚动

监听页面滚动

  • 给列表视图模型设置监听函数,每当列表视图发生滚动,就执行回调,获取滚动高度scrolltop
  • 通过scrolltop和itemHeight我们可以得到新的start以及end,从而获取到新的showList
  • 通过start和itemHeight我们可以给list设置偏移(translate),从而达到让start对应的数据展示在视图模型的效果

注意:列表视图模型和列表并不是一个东西,视图模型表示者页面供列表展示的一块区域,而列表表示的是需要展示的列表项总高度

这是列表视图模型

image-20220530183845436

这是列表

image-20220530183906181

列表中超出视图模型的节点就被隐藏了

为什么限制了展示列表项的长度(限制了dom数量),视图模型还能持续滚动?

给列表设置translate会增大列表的高度,既然list的高度变大了,那么视图模型就可以继续滚动

实现代码

​ 以vue3为例(不管是vue2或是vue3,实现虚拟列表的核心代码都是相同的,即监听滚动,赋新值)

<div ref="listWrap" class="list-wrap" @scroll="scrollListener">
    <div class="list" ref="List">
        <slot  v-for="item in showList" :songInfo="item" :key="item.id"></slot>
    </div>
  </div>
  setup(props) {
    const list = ref(props.list); //长列表数据
    const itemHeight = ref(props.itemHeight); //item高度
    const showNum = ref(props.showNum); //展示的数据
    const start = ref(props.start); //滚动过程中的开始索引
    const end = ref(props.end); //滚动过程中的结束索引
    const listWrap = ref(null); //获取列表视图模型节点
    const List = ref(null)//获取列表节点
    onMounted(() => {
        listWrap.value.style.height = itemHeight.value * showNum.value + "px";//设置列表视图模型的高度
    });
    const showList = computed(() => {
      //获取展示的列表
      return list.value.slice(start.value, end.value);
    });

    const scrollListener = (() => {
           //获取滚动高度
            let scrollTop = listWrap.value.scrollTop;
            //开始的数组索引
            start.value = Math.floor(scrollTop / itemHeight.value);
            //结束索引
            end.value = start.value + showNum.value;
            List.value.style.transform =  `translateY(${start.value * itemHeight.value}px)`//对列表项进行偏移
    })
    return {
      ...
    };
  },

效果:

GIF 2022-5-30 18-45-24

节点变化

可以看到不论列表如何变化,列表dom的数量并没有新增

GIF 2022-5-30 18-47-14

总结 

到此这篇关于vue长列表优化之虚拟列表实现的文章就介绍到这了,更多相关vue虚拟列表实现内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

vue长列表优化之虚拟列表实现过程详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

C++哈希表之闭散列方法的模拟实现详解

闭散列指(开放定址法)发生冲突时,如果哈希表没有被填满,则表内一定还有其他空闲位置,可以把冲突值放到下一个没有被占用的空余位置上。本文将模拟实现闭散列方法,需要的可以参考一下
2022-11-13

C++数组模拟之单链表与双链表和栈和队列的实现过程

这篇文章主要介绍了C++数组模拟之单链表与双链表和栈和队列的实现过程,了解内部原理是为了帮助我们做扩展,同时也是验证了一个人的学习能力,如果你想让自己的职业道路更上一层楼,这些底层的东西你是必须要会的,跟随下文来具体了解吧
2023-02-13

编程热搜

目录