Vue项目实践:使用滚动下拉分页优化大数据展示页面【通过防抖加标志位进行方案优化】

news2024/9/23 5:35:06

Vue项目实践:使用滚动下拉分页优化大数据展示页面

前言

        传统的分页机制通过点击页码来加载更多内容,虽然直观,但在处理大量数据时可能会导致用户体验不佳。相比之下,滚动下拉分页能够在用户滚动到页面底部时自动加载更多内容,既节省了用户操作,也使得数据的展示更加流畅自然。

准备工作

scrollTop,clientHeight,scrollHeight 详解

Vue项目实践:使用滚动下拉分页优化大数据展示页面

  1. scrollTop
    定义:scrollTop 属性表示元素在垂直方向上已经滚动过的距离。换句话说,它衡量的是元素内容顶部与视口顶部之间的距离。这个值通常是非负的,单位是像素。
    应用场景:当你需要知道元素内部滚动了多少或者想要手动设置滚动位置时,会用到这个属性。例如,实现“回到顶部”按钮功能时,可以设置 scrollTop0来瞬间返回顶部。
  2. clientHeight
    定义:clientHeight 表示元素可视区域的高度,即元素内容区的高度加上垂直边框和内边距(padding),但不包括水平滚动条(如果存在)、外边距或滚动条本身。这个值总是正的,单位也是像素。
    应用场景:当你需要计算元素实际显示给用户的高度时会用到 clientHeight,比如判断元素是否完全在视口内显示。
  3. scrollHeight
    定义:scrollHeight 表示元素的总高度,包括不可见的部分,也就是元素内容的总高度,不论内容是否在当前视口内可见。这包括了所有内边距、边框,但不包括外边距。对于没有滚动条的元素,scrollHeight 等于元素的 clientHeight
    应用场景:当你需要了解元素内容的完整高度,特别是用于判断是否还有更多内容可以滚动查看时,scrollHeight 就显得非常重要。比如,结合 scrollTopclientHeight来判断是否已经滚动到底部,从而实现无限滚动加载功能。

实现思路

在实现一个无限滚动(滚动加载更多)功能时,可以通过比较 scrollTop + clientHeightscrollHeight 来判断是否接近滚动底部。

实现

效果

Vue项目实践:使用滚动下拉分页优化大数据展示页面

HTML\CSS结构

注意:一定要设置需要滚动盒子device-content的高度,及其overflow: hidden; overflow-y: auto;样式属性,使其具有滚动。通过handleScroll进行监听父盒子的滚动状态,其中device-box是父盒子中的内容列表。

<a-spin dot :loading="deviceLoading" tip="正在加载...">
  <div class="device-content" @scroll="handleScroll">
    <div v-for="device in deviceList" :key="device.id" class="device-box">
      <div class="device-con-box">
        <div class="device-con-img"></div>
        <div class="device-con-text">
          <div class="device-con-text-top">{{
            device.detectDeviceFullName
          }}</div>
          <div class="device-con-text-bottom">
            <span
              v-if="device.runStatusKey === 'device_run_status:offline'"
              class="offline"
              >离线</span
            >
            <span
              v-if="device.runStatusKey === 'device_run_status:working'"
              class="working"
              >工作</span
            >
            <span
              v-if="device.runStatusKey === 'device_run_status:waiting'"
              class="waiting"
              >空闲</span
            >
            <span
              v-if="device.runStatusKey === 'device_run_status:breakdown'"
              class="breakdown"
              >故障</span
            >
          </div>
        </div>
      </div>
    </div>
  </div>
</a-spin>

CSS结构:

.device-content {
  width: 100%;
  height: 645px;
  overflow: hidden;
  overflow-y: auto;
  .device-box {
    cursor: pointer;
    height: 148px;
    width: 400px;
    float: left;
    border-radius: 12px;
    border: 1px solid #ccc;
    margin-bottom: 6px;
    margin-right: 6px;
    .device-con-box {
      height: 98px;
      width: 305px;
      margin: 0px auto;
      margin: 20px 68px 37px 48px;
      display: flex;
      .device-con-img {
        height: 80px;
        width: 80px;
        background: url('../../assets/images/deviceImg.png');
      }
      .device-con-text {
        width: 220px;
        height: 100%;
        padding-left: 16px;
        .device-con-text-top {
          height: 68px;
          width: 120%;
          padding-top: 23px;
          font-size: 14px;
          font-weight: 400;
          color: #000;
        }
        .device-con-text-bottom {
          height: 30px;
          width: 100%;
          font-family: Microsoft YaHei UI;
          font-size: 24px;
          font-weight: 700;
          line-height: 22px;
          text-align: left;
          color: #19cd61;
        }
        .line-division {
          margin-left: 10px;
          margin-right: 10px;
          color: #e7e7e7;
          font-size: 18px;
          position: relative;
          top: -3px;
        }
      }
    }
  }
}

监听父盒子函数handleScroll

检查用户是否已经滚动到容器的底部,如果滚动到了底部,再次判断页面的数据是否大于总条数,如果小于总条数,则继续进行加载下一页,如果大于总条数,则不进行加载。【距离顶部的距离+可视区高度>=元素总高度

// eslint-disable-next-line no-use-before-define
const handleScroll = (e: Event) => {
  const target = e.target as HTMLElement;
  // 检查用户是否已滚动到容器底部附近
  if (target.scrollTop + target.clientHeight >= target.scrollHeight - 10) {
    // 此条件检查是否还有更多页面的数据需要加载
    if (pagination.current * pagination.pageSize < pagination.total) {
      fetchData({ ...basePagination, current: pagination.current + 1 });
    }
  }
} 

但是会出现,当触底的时候,多次请求分页列表,导致页面存储的数据大于数据库中数据的总条数。

Vue项目实践:使用滚动下拉分页优化大数据展示页面
处理以上触底时多次请求有两种方式可解决

使用防抖技术

使用防抖技术,确保在短时间内只处理一次滚动事件。

// 防抖函数
function debounce(func: any, wait: any) {
  let timeout: number | undefined;

  // eslint-disable-next-line func-names
  return function (...args: any[]) {
    // eslint-disable-next-line @typescript-eslint/no-this-alias
    const context: any = this;

    clearTimeout(timeout);
    timeout = window.setTimeout(() => {
      func.apply(context, args);
    }, wait);
  };
}

添加标志位

添加一个标志位isFetching 来防止在请求完成之前再次发送请求。

const isFetching = ref(false);

const fetchData = async (
  params: PolicyParams = { current: 1, pageSize: 20 }
) => {
  if (isFetching.value) return;
  isFetching.value = true;
  setLoading(true);
  try {
    const { data } = await getDetectDeviceMonitorPage(params);
    pagination.current = params.current;
    pagination.total = data.total;
    if (params.current === 1) {
      deviceList.value = data.data;
    } else {
      deviceList.value = [...deviceList.value, ...data.data];
    }
  } catch (err) {
    // you can report use errorHandler or other
  } finally {
    setLoading(false);
    isFetching.value = false;
  }
};

const handleScroll = (e: Event) => {
  const target = e.target as HTMLElement;
  // 检查用户是否已滚动到容器底部附近
  if (target.scrollTop + target.clientHeight >= target.scrollHeight - 10) {
    // 此条件检查是否还有更多页面的数据需要加载
    if (!isFetching.value && pagination.current * pagination.pageSize < pagination.total) {
      fetchData({ ...basePagination, current: pagination.current + 1 });
    }
  }
};

通过添加防抖和标志位后的效果
Vue项目实践:使用滚动下拉分页优化大数据展示页面
完美解决触底出现多次分页请求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1813764.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

实现JWT认证与授权的Spring Boot项目详解

我们将详细介绍如何使用JWT&#xff08;JSON Web Tokens&#xff09;结合Spring Boot框架实现用户认证和授权系统。此方案将包括用户注册、登录以及通过JWT令牌进行后续请求的身份验证过程。我们将从引入必要的依赖开始&#xff0c;然后逐步构建项目的各个部分&#xff0c;包括…

如何查看当前的gruop_id 的kafka 消费情况 这个可以查看到是否存在消费阻塞问题

如何查看当前的gruop_id 的kafka 消费情况 这个可以查看到是否存在消费阻塞问题 命令如下: /kafka/bin/kafka-consumer-groups.sh --bootstrap-server 127.0.0.1:9092 --group GWW --describe 其中 127.0.0.1 为zookeeper 服务器ip GWW 为对应要查看的group_id 如下…

从零到一建设数据中台(番外篇)- 数据中台UI欣赏

番外篇 - 数据中台 UI 欣赏 话不多说&#xff0c;直接上图。 数据目录的重要性&#xff1a; 数据目录是一种关键的信息管理工具&#xff0c;它为组织提供了一个全面的、集中化的数据资产视图。 它不仅记录了数据的存储位置&#xff0c;还详细描述了数据的结构、内容、来源、使…

800W-2300W-4500W-7000W线绕电阻器的选型参考

EAK线绕电阻器将普通电阻器材料的高脉冲稳定性与优化的导热和高度保护相结合。安装在导热表面上可进一步改善散热并提高稳定性。 EAK提供各种外壳设计和材料&#xff08;如铝和钢&#xff09;的导线电阻器。它们符合 UL508 的要求&#xff0c;在用作制动、充电、放电或加热电阻…

Java面试八股之静态变量和实例变量的区别有哪些

Java静态变量和实例变量的区别有哪些 存储位置和生命周期&#xff1a; 静态变量&#xff1a;静态变量属于类级别&#xff0c;存储在Java的方法区&#xff08;或称为类区&#xff0c;随JVM实现而异&#xff0c;现代JVM中通常在元数据区内&#xff09;&#xff0c;并且在类首次…

Rocky Linux 9.4 部署Zabbix 7.0

文章目录 Zabbix基本概念zabbix介绍zabbix特性zabbix结构 安装Zabbix主机名配置配置Zabbix-Server(1)禁用EPEL提供的Zabbix软件包(2)安装Zabbix Server、Web前端、Agent(3)创建初始数据库(4)Zabbix server配置数据库(5)为Zabbix前端配置PHP(6)启动Zabbix server和agent进程(7)放…

Windows电脑清理C盘内存空间

ps&#xff1a;过程截图放在篇末 一、%tmp%文件 win R键呼出运行窗口&#xff0c;输入 %tmp% 自动进入tmp文件夹&#xff0c;ctrl A全选删除 遇到权限不足&#xff0c;正在运行&#xff0c;丢失的文件直接跳过即可 二、AppData文件夹 1、pipcache 在下列路径下面&…

Amortized bootstrapping via Automorphisms

参考文献&#xff1a; [MS18] Micciancio D, Sorrell J. Ring packing and amortized FHEW bootstrapping. ICALP 2018: 100:1-100:14.[GPV23] Guimares A, Pereira H V L, Van Leeuwen B. Amortized bootstrapping revisited: Simpler, asymptotically-faster, implemented. …

代理设计模式之JDK动态代理CGLIB动态代理原理与源码剖析

代理设计模式 代理模式(Proxy),为其它对象提供一种代理以控制对这个对象的访问。如下图 从上面的类图可以看出,通过代理模式,客户端访问接口时的实例实际上是Proxy对象,Proxy对象持有RealSubject的引用,这样一来Proxy在可以在实际执行RealSubject前后做一些操作,相当于…

MTK烧录USB驱动下载

下载链接 https://www.catalog.update.microsoft.com/Search.aspx?qMediaTek%20USB%20Port 驱动安装教程 https://miuiver.com/install-official-mediatek-driver/

中科数安 |-公司办公透明加密系统,数据防泄漏软件

#数据防泄漏软件# 中科数安是一家专注于提供企业级数据防泄漏解决方案的公司&#xff0c;其办公透明加密系统是专为保护企业内部核心数据资料设计的。 PC地址&#xff1a;——www.weaem.com 该系统通过以下主要功能模块实现高效的安全防护&#xff1a; 文档透明加密&#xff1…

惠州惠城:可燃气体报警器定期校准检测,安全更放心

在惠州惠城这片繁华的土地上&#xff0c;工业发展日新月异&#xff0c;安全问题愈发受到重视。其中&#xff0c;可燃气体报警器作为预防火灾和爆炸事故的重要设备&#xff0c;正在越来越多的场所得到应用。 今天&#xff0c;佰德就来探讨一下可燃气体报警器在惠州惠城的重要性…

PV 操作

PV 操作是一种实现进程 互斥 与 同步 的有效方法。PV 操作与信号量的处理相关&#xff0c;P 表示 passeren 通过的意思&#xff0c;V 表示 vrijgeven 释放的意思. 包含在 1965 年, 由荷兰人 Dijkstra 提出的信号量机制; (同是 银行家算法 和 最短路径算法 的提出者) 术语: sema…

Pytorch 实现简单的 线性回归 算法

Pytorch实现简单的线性回归算法 简单 tensor的运算 Pytorch涉及的基本数据类型是tensor&#xff08;张量&#xff09;和Autograd&#xff08;自动微分变量&#xff09; import torch x torch.rand(5, 3) #产生一个5*3的tensor&#xff0c;在 [0,1) 之间随机取值 y torch.o…

ATFX汇市:非农数据超预期靓丽,美指重新站上105关口

ATFX汇市&#xff1a;6月7日&#xff0c;美国劳工统计局公布5月份非农就业报告&#xff0c;其中提到&#xff1a;5月份增加了27.2万个岗位&#xff0c;大幅高于前值16.5万人&#xff0c;数据超预期靓丽&#xff1b;几个行业的就业人数继续呈上升趋势&#xff0c;其中医疗领域增…

操作系统 c语言模仿 磁盘文件操作

1&#xff0e;实验目的 深入了解磁盘文件系统的实现。 2&#xff0e;实验预备知识 文件的操作&#xff1b; 文件的逻辑结构和物理结构&#xff1b; 磁盘空间的管理&#xff1b; 磁盘目录结构。 3&#xff0e;实验内容 设计一个简单的文件系统&#xff0c;用文件模拟磁盘&…

springboot+vue前后端分离项目中使用jwt实现登录认证

文章目录 一、后端代码1.响应工具类2.jwt工具类3.登录用户实体类4.登录接口5.测试接口6.过滤器7.启动类 二、前端代码1.登录页index 页面 三、效果展示 一、后端代码 1.响应工具类 package com.etime.util;import com.etime.vo.ResponseModel; import com.fasterxml.jackson.…

RAG核心算法

一、分块与向量化 首先,我们的目标是创建一个向量索引,用以代表我们文档的内容,然后在运行时寻找所有这些向量与查询向量之间的最小余弦距离,以匹配最接近的语义含义。 1、分块 由于 Transformer 模型具有固定的输入序列长度,即便输入上下文窗口很大,一个句子或几个句…

【全网最有效,保姆级教程】KEPServerEX 6下载安装解决时长问题

1、下载KEPServer KEPServerEX 6下载链接(为了防止版本不兼容&#xff0c;一定要使用下面链接里面的版本&#xff01;)&#xff1a; https://pan.baidu.com/s/19pAXzhWa5nxduU3mi1V4Nw?pwd1234 提取码:1234 2、安装KEPServer 基本上都是默认下一步&#xff0c;选择中文&…

python中用列表实现栈

【小白从小学Python、C、Java】 【考研初试复试毕业设计】 【Python基础AI数据分析】 python中用列表实现栈 选择题 以下代码最后一次输出的结果是&#xff1f; stack [] stack.append(1) stack.append(2) stack.append(3) print(【显示】stack ,stack) print(【显示】stack.…