Debug-029-el-table实现自动滚动分批请求数据

embedded/2024/10/20 14:39:03/

前情提要

        最近做了一个小优化,还是关于展示大屏方面的。大屏中使用el-table展示列表数据,最初的方案是将数据全部返回,确实随着数据变多有性能问题,有时请求时间比较长。这里做的优化就是实现列表的滚动到距离底部一定高度时再次请求接口数据,实现分批请求提升性能。然后这里也实现让el-table自动滚动的功能

思路

  (1) 自动滚动:

        先给el-table绑定ref,拿到组件实例,找到真实滚动的那部分内容。这一步需要耐心点。然后就是监听这个滚动区域的滚动事件,利用视图展示区域(clientHeight)+垂直方向超出部分(scrollTop)和 内容实际的总高度三者的(scrollHeight)的关系判断内容是否滚动到底部,需要添加定时器增加scrollTop的高度,以达到自动滚动的效果,最终滚动完毕给出判断回到el-table顶部重新滚动(scrollTop置为0)。

备注:最初是查找官方文档,发现使用el-tbale的话没有直接可以支持自动滚动的属性,但是vue3中有v-infinite-scroll这个指令,不过我没试过放在el-table中使用,有机会各位可以去尝试一下。

  (2) 分批次请求数据

        还是要先拿到实际滚动的那块区域,然后还是监听滚动事件,由于增加了自动滚动,我开始的思路是把自动滚动和用户手动滚动两个情况分开,不过我在review的时候尝试了一下,确实是不需要区分的,不管是自动滚动还是手动滚动这里只需要考虑好滚动到合适的高度请求数据即可,拼接在之前的tbaleData中,直至达到总数停止

自动滚动

代码:

//自动滚动封装在table中,是否自动滚动由父组件传入autoScroll决定//onMounted:组件挂载完成后执行。若autoScroll为真,则调用  //createScroll初始化滚动功能。
onMounted(() => {props.autoScroll && createScroll()
})//onUnmounted:组件卸载前执行。若autoScroll为真,则调用  //clearScroll清理滚动相关资源
onUnmounted(() => {props.autoScroll && clearScroll()
})const clearScroll = () => {if(!props.autoScroll) returnclearInterval(timer)timer = null
}
const createScroll = () => {if(!props.autoScroll) returnclearScroll()// 拿到 tableconst table = tableref.value.layout.table.refs// 拿到可以滚动的元素const tableWrapper = table.bodyWrapper.firstElementChild.firstElementChildtimer = setInterval(() => {tableWrapper.scrollTop += 1.5// 判断是否滚动到底部,如果到底部了置为0(可视高度+距离顶部=整个高度)if (tableWrapper.clientHeight + tableWrapper.scrollTop >= (tableWrapper.scrollHeight - 5))tableWrapper.scrollTop = 0}, 100)
}

分批请求数据

代码:

const jyTableRef = ref<InstanceType<typeof ElTable>>()
const wrapRef = ref() // 滚动条实例
const pageNum = ref(1)
const count = ref('0') // 设备总数
const isRequest = ref(true) // 控制请求的时机// 获取实时监测表格数据
async function getRealTimeModelData(id: any) {if (mockData.value.length > +count.value) return // 如果已经超出最大范围,停止查询const result = await getRealTimeModelDataApi({groupId: id,pageSize: 50,pageNum: pageNum.value,//  环境变量// tenantId: 'jybfgs'})console.log('result', result)count.value = result.count || 0 // 从图表的接口获取总条数,列表的总数会变不能用mockData.value.push(...(result.list || [])) // 将每次请求的数据拼接缓存在前端// isUserScroll.value = 2isRequest.value = false// mockData.value = res.list || []sortTableData(sortName.value, sortType.value)filterHandler(filterDeviceStatus.value, filterProp.value)
}// 滚动事件
const scrolling = async (event:any) => {console.log('scrolling')const scrollHeight = event.target.scrollHeightconst clientHeight = event.target.clientHeight// isScrollingBottom.value = scrollHeight - clientHeight === event.target.scrollTop// 是否滚动的底部console.log('event', isRequest.value, scrollHeight, clientHeight, (scrollHeight - clientHeight), event.target.scrollTop)// 有时接口数据返回较慢,这里不在触底时请求刷新,而是在内容达到一半时请求新数据if (((scrollHeight - clientHeight) / 2) <= event.target.scrollTop && !isRequest.value) {console.log('自动滚动')isRequest.value = !isRequest.value// 页码+1pageNum.value++getRealTimeModelData(props.id)}
}onMounted(() => {getRealTimeModelData(props.id)console.log(1234455, jyTableRef.value!.tableref.scrollBarRef.wrapRef)// 获取表格内的滚动条,并监听滚动事件wrapRef.value = jyTableRef.value!.tableref.scrollBarRef.wrapRef// 监听滚动事件wrapRef.value.addEventListener('scroll', scrolling)
})onUnmounted(() => {// if (timer) clearInterval(timer)// 移出监听事件wrapRef.value.removeEventListener('scroll', scrolling)
})

小结&收获

        由于时间有限,这里的代码确实不能直接cv,我是直接从项目中截取的关键部分,省略了一些引用或者变量声明。对我自己来讲我已经测试很多遍了,所以才比较清晰。这里的代码主要是一个备份和引导作用。对大家来说我觉得重要的还是思路吧,我看大家常规思路都是这样做的,大家可以下去自己尝试。通过回顾之前开发的这个功能,我想再总结一下对于这个需求几个比较重要关键的技术点和经验吧:

(1)首先如果是使用开源的ui组件库比如elementui,那么肯定是先去官网看对应组件是否存在相关功能的属性和方法,如果没有可以直接使用的或者相关辅助我们实现功能的话再去自己百度也好或者AI调研开发。

(2)这次大屏的两个功能点都离不开的一点就是我们对于el-table都去给它绑定ref,目的就是拿到它的组件实例,然后可以方便我们操作上面的方法,dom和属性,以后的开发中类似的功能都是离不开组件实例的,经常会用到。这一点我认为需要多多练习,自然能熟能生巧。

(3)监听滚动事件。这一步算是这次迭代的核心内容吧。这里我们又要知道的两个东西,一个是监听滚动事件wrapRef.value.addEventListener('scroll', scrolling),addEventListener这个监听器非常好用,对于所有dom的相关操作都可以用它来监听。也是熟能生巧,其中的event形参中存在所有你想要的属性;另一个就是这次功能的判断条件(请求数据的时机)一个常见公式:

//当数据滚动到列表底部时(数据加载完毕时)此等式成立内容总高度   -  视图高度      =    内容超出顶部的高度
scrollHeight  - clientHeight  = scrollTop

正常来讲(scrollHeight  - clientHeight  )的高度一定是大于 scrollTop的,只有当数据滚动到列表底部时此等式成立,也即是数据加载完的时候成立。所以常规思路就是利用这个时机去来触发新请求拼接新数据。当然这三个属性在监听的scrolling方法中的event形参中全都有。

        不过在我的代码中我没有在触底的时候二次请求,而是选择在内容滚动到一半的时候就提前请求第二次的数据。

(((scrollHeight - clientHeight) / 2) <= event.target.scrollTop && !isRequest.value)

这里还准备了一个变量 isRequest去防止满足条件多次请求的情况,并且接口返回时间有时候比较长,由于自动滚动会导致触底回到列表第一条重头滚动,所以不选择在触底时请求而是在内容滚动一半就提前请求。

而且还有一点需要注意的是,条件一定不能给等于而是要给小于等于或者大于等于,因为当浏览器放缩不同时,是会导致这个高度不存在整数的情况,等式就不成立了,所以尽量给一个范围,这样就必然会被触发。

下面是菜鸟教程的原话:

这三者之间的关系不熟悉的话具体详解再推荐一篇文章给大家:

JavaScript第 11 篇,JavaScript中的scrollTop(JavaScript中的scrollTop,JS滚动到顶部)-CSDN博客文章浏览阅读1.9w次,点赞25次,收藏96次。⭐scrollTop是JavaScript中一个非常有用且重要的方法,它用于获取或设置元素的垂直滚动条位置,实现各种滚动相关的功能,无论是回到顶部、滚动到指定位置还是监听滚动事件,都需要用到scrollTop,在本文中,我们将深入了解scrollTop的用法和实际应用,这是一张scrollTop的关系图,仅供参考_scrolltophttps://blog.csdn.net/weixin_65793170/article/details/129836174(4)封装自定义指令。对于这种列表滚动来讲,一般需要操作dom的情况可以封装为自定义指令,然后原则就是“开箱即用”,尽量让别人直接使用即可,不需要添加太多逻辑,尽量封装到位。方便之后有需要滚动的table可以一次到位,方便之后开发。(前辈经验:如果是涉及到dom监听,操作相关的服用,自定义指令是非常好的方案)

分享

        这里还有几篇我之前看到的思路差不多,这里给大家分享一下,便于大家加深理解(代码不重要,思路很重要)。

el-table不使用分页组件,仅滚动条实现加载下一页数据_el-table滚动加载-CSDN博客文章浏览阅读622次,点赞4次,收藏3次。el-table不使用分页组件,仅滚动条实现加载下一页数据_el-table滚动加载https://blog.csdn.net/csdnyp/article/details/136315835

使用el-table实现自动滚动_el-table自动滚动-CSDN博客文章浏览阅读1.4k次,点赞4次,收藏6次。在前端开发大屏的时候,我们会用到表格数据展示,有时候为了使用户体验更加好,会增加表格自动滚动。下边我将以示例代码,用element UI的el-table来讲一下。2 通过判断dom的scrollHeight和scrollTop的关系,来实现滚动。1 .增加dom监听,鼠标放上去的时候不滚动,鼠标离开的时候滚动。3.当不需要使用,或者表格需要重新渲染的时候,我们需要清掉定时器。_el-table自动滚动https://blog.csdn.net/weixin_38912662/article/details/140657947ant design vue中table表格滚动加载实现思路_vue.js_脚本之家在处理一写数据量特别大的情况下,我们不能把后端的数据一次性全部拿到前端在table表格中展示,为了考虑性能优化,使用了滚动加载表格数据,这篇文章主要介绍了ant design vue中table表格滚动加载实现思路,需要的朋友可以参考下icon-default.png?t=O83Ahttps://www.jb51.net/javascript/323819ttr.htmel-table实现表格滚动上拉加载更多(Vue3)_el-table滚动加载-CSDN博客文章浏览阅读1k次。【代码】el-table实现表格滚动上拉加载更多(Vue3)_el-table滚动加载https://blog.csdn.net/qq_48665028/article/details/136883338


http://www.ppmy.cn/embedded/129013.html

相关文章

UDP协议和TCP协议

UDP协议&#xff1a; 是一种无连接的、简单的传输层通信协议&#xff0c;它在IP协议&#xff08;网络层&#xff09;之上提供服务。 特点&#xff1a; 无连接&#xff1a;在数据传输前&#xff0c;发送方和接收方之间不需要建立连接&#xff0c;可以直接发送数据。 简单&…

读数据工程之道:设计和构建健壮的数据系统14源系统

1. 源系统中的数据生成 1.1. 数据工程师的工作是从源系统获取数据&#xff0c;对其进行处理&#xff0c;使其有助于为下游用例提供服务 1.2. 数据工程师的角色将在很大程度上转向理解数据源和目的地之间的相互作用 1.3. 数据工程的最基本的数据管道任务——将数据从A移动到B…

Threejs 实现3D 地图(01)创建基本场景

"d3": "^7.9.0", "three": "^0.169.0", "vue": "^3.5.10" <script setup> import { onMounted,ref } from vue import * as THREE from three import * as d3 from "d3"; //莫开托坐标 矫正地图…

Mybatis-plus

Springboot3Mybatis3.5 基本框架环境依赖导入配置文件实体类业务类结构 基本功能——提供的mapper接口及实现插入删除——返回受影响行数修改数据查询方法自定义mapper&#xff08;和mybatis一样&#xff09; 相关功能——提供的Service方法Service层搭建相关方法添加记录插入或…

SpringCloud第三章:客户端负载均衡与服务调用

正常本章节应该讲解Netflix Ribbon&#xff0c;由于从Netflix Eureka Client 3.0版本开始内置Ribbon实现机制&#xff0c;不需要单独依赖Ribbon&#xff0c;如果引入Ribbon会报错 java.lang.IllegalStateException: No instances available for XXXXXX&#xff0c;并且想要修改…

1/2∥w∥^2 :这是w 的二次项,偏导数为 w

此公式出现在线性可分支持向量机基于拉格朗日函数L(w,b,α)对w求导的公式中。为什么 1 2 ∥ w ∥ 2 \frac{1}{2} \|\mathbf{w}\|^2 21​∥w∥2 对 w \mathbf{w} w 的偏导数是 w \mathbf{w} w。这个问题涉及到向量的微分运算。 1. 复习&#xff1a;向量的范数 我们首先来看…

DBdoctor推出无Agent轻量级纳管解决方案

目录 背景 DBdoctor推出无Agent轻量级纳管解决方案 方案优势&#xff1a; 实例纳管方式&#xff1a; 无Agent纳管可体验哪些功能&#xff1f; 1.全量SQL审核功能 2.实例巡检功能 3.性能洞察功能 4.基础监控功能 总结 背景 在数字化时代&#xff0c;数据库作为信息系…

pdf文件怎样一张纸打印四页

在日常工作和学习中&#xff0c;我们经常会遇到需要将PDF文件中的多页内容合并打印到一张纸上的情况&#xff0c;比如将四页内容打印到一张A4纸上&#xff0c;以节省纸张和成本。同时&#xff0c;在打开pdf文件的方式&#xff0c;一般都是通过电脑浏览器打印&#xff0c;因此对…