​​【面试题】后端返回十万条数据前端怎么处理?vue实现虚拟列表

简介: vue实现虚拟列表

一.前言

想必大家在面试的时候会经常被问到后端一下返回十万条数据前端怎么进行处理,二面问。这是一个有关项目优化的问题。前面我写了一篇关于时间分片(数据分割)和滚动触底加载的文章,在这我就不写了,感兴趣的大家可以去看看,有源码,很详细。

二.为嘛这个面试题的答案是虚拟列表?

首先遇到这种大数据处理,肯定想到的是数据懒加载,那就是虚拟列表、时间分片、滚动加载,当然最常用的方法是分页,但是产品经理他不想让你这么干,最近项目优化用到这个方案,详细总结一下

    时间分片:通过定时器在规定时间内更新数据,数据是一种伪实时性的,给人一种感觉是实时更新,其实不是,因为你定时器时间跟websocket推送数据的时间间隔不一样。而且时间分片约到后面页面越卡,真实项目经验。

    滚动条触底加载:通过监听滚动条时间,只要触底就进行调接口返回数据。一下返回十万条数据真渲染不出来,而且你不能一触底就调接口,这样也是耗费性能的,所以滚动条触底加载只适合少量数据

    虚拟列表:只对可见区域的数据进行渲染,对非可见区域的数据只做缓存,不渲染。以此来减少性能消耗,提高用户体验。它是长列表的一种优化方案。性能可以说是数据懒加载中的最优化方案。

三.虚拟列表的实现思路(重点:面试过程中就这么回答)

1.首先你得写一个div,这个div得固定高度。通过css的overflow属性使其允许纵向y轴滚动。
2.计算可视区域内可以显示的数据条数。可以用可视区域的高度除以一条数据的高度。
3.监听滚动条,当滚动条滚动时计算出被卷起的数据的高度。
4.计算这个可视区域内数据的起始索引值,也就是第一条数据的下标。通过滚动条卷起的高度除以单条数据的高度,这块可能大家一下反应不过来,起始坐标最开始是0对吧。卷起的高度除以单条数据的高度是不是就是卷起的数据的数量,那么他的索引值是不是就是数据的数量。假如被卷起四条数据,那么第五条数据索引值是不是四。
5.计算区域结束数据的索引。通过起始索引加上可视区域显示的数据条数
6.截取数据渲染到可视区域。从起始索引截取到结束索引。
7.计算起始索引在整个列表中的偏移位置并设置到列表上,因为每次都不可能滚动到整条数据上。
这样一个基本的虚拟列表就有了,当然大家可以根据需求做一些性能优化,比如防抖节流,如果用户一直快速滚动问题。

四.小demo.(代码+注释)


<template>
    <div :style="{ height: `${contentHeight}px` }" class="content_box" @scroll="scroll">
        <!--这层div是为了把高度撑开,让滚动条出现,height值为所有数据总高-->
        <div :style="{
   
    'height': `${
     
     itemHeight * (listAll.length)}px`, 'position': 'relative' }">
            <!--可视区域里所有数据的渲染区域-->
            <div :style="{
   
    'position': 'absolute', 'top': `${
     
     top}px` }">
                <!--单条数据渲染区域-->
                <div v-for="(item, index) in showList" :key="index" class="item">
                    {
   
   {
   
    item }}
                </div>
            </div>
        </div>
    </div>
</template>

<script>
export default {
   
   
    name: "list",
    data () {
   
   
        return {
   
   
            listAll: [],  //所有数据
            showList: [],  //可视区域显示的数据
            contentHeight: 500,  //可视区域高度
            itemHeight: 30,      //每条数据所占高度
            showNum: 0,  //可是区域显示的最大条数
            top: 0, //偏移量
            scrollTop: 0,  //卷起的高度
            startIndex: 0,  //可视区域第一条数据的索引
            endIndex: 0,  //可视区域最后一条数据后面那条数据的的索引,因为后面要用slice(start,end)方法取需要的数据,但是slice规定end对应数据不包含在里面
        }
    },
    methods: {
   
   
        //构造10万条数据
        getList () {
   
   
            for (let i = 0; i < 100000; i++) {
   
   
                this.listAll.push(`我是bug天选之子的第${
     
     i}数据呀`)
            }
        },
        //计算可视区域数据
        getShowList () {
   
   
            this.showNum = Math.ceil(this.contentHeight / this.itemHeight);  //可视区域最多出现的数据条数,值是小数的话往上取整,因为极端情况是第一条和最后一条都只显示一部分
            this.startIndex = Math.floor(this.scrollTop / this.itemHeight);   //可视区域第一条数据的索引
            this.endIndex = this.startIndex + this.showNum;   //可视区域最后一条数据的后面那条数据的索引
            this.showList = this.listAll.slice(this.startIndex, this.endIndex)  //可视区域显示的数据,即最后要渲染的数据。实际的数据索引是从this.startIndex到this.endIndex-1
            const offsetY = this.scrollTop - (this.scrollTop % this.itemHeight);  //在这需要获得一个可以被itemHeight整除的数来作为item的偏移量,这样随机滑动时第一条数据都是完整显示的
            this.top = offsetY;
        },
        //监听滚动事件,实时计算scrollTop
        scroll () {
   
   
            this.scrollTop = document.querySelector('.content_box').scrollTop;  //element.scrollTop方法可以获取到卷起的高度
            this.getShowList();
        }
    },
    mounted () {
   
   
        this.getList();
        this.scroll();
    }
}
</script>

<style scoped>
.content_box {
   
   
    overflow: auto;
    /*只有这行代码写了,内容超出高度才会出现滚动条*/
    width: 700px;
    border: 1px solid red;
}

/*每条数据的样式*/
.item {
   
   
    height: 30px;
    padding: 5px;
    color: #666;
    box-sizing: border-box;
}
</style>

```

运行效果:
8.1.png

相关文章
|
1月前
|
存储 安全 Java
每日大厂面试题大汇总 —— 今日的是“美团-后端开发-一面”
文章汇总了美团后端开发一面的面试题目,内容涉及哈希表、HashMap、二叉树遍历、数据库索引、死锁、事务隔离级别、Java对象相等性、多态、线程池拒绝策略、CAS、设计模式、Spring事务传播机制及RPC序列化工具等。
39 0
|
8天前
|
JavaScript API 开发工具
<大厂实战场景> ~ Flutter&鸿蒙next 解析后端返回的 HTML 数据详解
本文介绍了如何在 Flutter 中解析后端返回的 HTML 数据。首先解释了 HTML 解析的概念,然后详细介绍了使用 `http` 和 `html` 库的步骤,包括添加依赖、获取 HTML 数据、解析 HTML 内容和在 Flutter UI 中显示解析结果。通过具体的代码示例,展示了如何从 URL 获取 HTML 并提取特定信息,如链接列表。希望本文能帮助你在 Flutter 应用中更好地处理 HTML 数据。
91 1
|
10天前
|
缓存 前端开发 JavaScript
"面试通关秘籍:深度解析浏览器面试必考问题,从重绘回流到事件委托,让你一举拿下前端 Offer!"
【10月更文挑战第23天】在前端开发面试中,浏览器相关知识是必考内容。本文总结了四个常见问题:浏览器渲染机制、重绘与回流、性能优化及事件委托。通过具体示例和对比分析,帮助求职者更好地理解和准备面试。掌握这些知识点,有助于提升面试表现和实际工作能力。
42 1
|
14天前
|
监控 JavaScript 前端开发
前端的混合之路Meteor篇(六):发布订阅示例代码及如何将Meteor的响应数据映射到vue3的reactive系统
本文介绍了 Meteor 3.0 中的发布-订阅模型,详细讲解了如何在服务器端通过 `Meteor.publish` 发布数据,包括简单发布和自定义发布。客户端则通过 `Meteor.subscribe` 订阅数据,并使用 MiniMongo 实现实时数据同步。此外,还展示了如何在 Vue 3 中将 MiniMongo 的 `cursor` 转化为响应式数组,实现数据的自动更新。
|
14天前
|
JSON 分布式计算 前端开发
前端的全栈之路Meteor篇(七):轻量的NoSql分布式数据协议同步协议DDP深度剖析
本文深入探讨了DDP(Distributed Data Protocol)协议,这是一种在Meteor框架中广泛使用的发布/订阅协议,支持实时数据同步。文章详细介绍了DDP的主要特点、消息类型、协议流程及其在Meteor中的应用,包括实时数据同步、用户界面响应、分布式计算、多客户端协作和离线支持等。通过学习DDP,开发者可以构建响应迅速、适应性强的现代Web应用。
|
27天前
|
JavaScript 前端开发 Python
django接收前端vue传输的formData图片数据
django接收前端vue传输的formData图片数据
26 4
|
8天前
|
JSON Dart 数据格式
<大厂实战场景> ~ flutter&鸿蒙next处理后端返回来的数据的转义问题
在 Flutter 应用开发中,处理后端返回的数据是常见任务,尤其涉及转义字符时。本文详细探讨了如何使用 Dart 的 `dart:convert` 库解析包含转义字符的 JSON 数据,并提供了示例代码和常见问题的解决方案,帮助开发者有效处理数据转义问题。
103 0
|
1月前
|
JavaScript 前端开发
vue3教程,如何手动获取后端数据(入门到精通3,新人必学篇)
本文提供了一个Vue 3教程,讲解了如何使用axios库手动从后端获取数据,包括安装axios、配置后端访问地址、编写路由地址、发起HTTP请求以及在组件中读取和打印响应数据的步骤。
233 0
vue3教程,如何手动获取后端数据(入门到精通3,新人必学篇)
|
1月前
|
JavaScript 前端开发
vue尚品汇商城项目-day01【8.路由跳转与传参相关面试题】
vue尚品汇商城项目-day01【8.路由跳转与传参相关面试题】
29 0
vue尚品汇商城项目-day01【8.路由跳转与传参相关面试题】
|
14天前
|
NoSQL 前端开发 MongoDB
前端的全栈之路Meteor篇(三):运行在浏览器端的NoSQL数据库副本-MiniMongo介绍及其前后端数据实时同步示例
MiniMongo 是 Meteor 框架中的客户端数据库组件,模拟了 MongoDB 的核心功能,允许前端开发者使用类似 MongoDB 的 API 进行数据操作。通过 Meteor 的数据同步机制,MiniMongo 与服务器端的 MongoDB 实现实时数据同步,确保数据一致性,支持发布/订阅模型和响应式数据源,适用于实时聊天、项目管理和协作工具等应用场景。

热门文章

最新文章