当前位置: 首页 > news >正文

koa-vue的分页实现

1.引言

    最近确实体会到了前端找工作的难处,不过大家还是要稳住心态,毕竟有一些前端大神说的有道理,前端发展了近20年,诞生了很多leader级别的大神,这些大神可能都没有合适的坑位,我们新手入坑自然难一些,前端现在对于新手的高要求也能够理解,只能硬着头皮完善自我了。而且距离自己3月20找工作底线时间还有两周,同花顺和恒生电子的笔试在还进展中,实在不行真得二战我倒也不怕。闲来无聊写一篇“应用文”吧(不过最近应用文会大幅减少,毕竟讲不清楚原理才是真得凉凉)。

2.场景描述

    我们经常遇到前端列表,需要进行分页处理,一般前端会说那是后端的任务,但是其实前端也是有工作量的,后端的分页任务其实不大,如果会一点sql语句就明白了,一句sql就能够实现(当然我这里没有包括必要参数检测和优化、错误反馈、防注入等内容)。
    在实现上,对于后端而言,主要是怎么告诉前端已经没有数据了,对于前端而言怎么确定需要再次请求数据了,另外前端还需要对数据进行缓存,提高性能。

3.后端设计与实现

    后端代码如下,主要做的是前端传入参数的检测和数据是否查询完毕了。说一下思路,参数检测可以利用强制转换来判断传入的参数的类型,包括是否传入、传入的参数是否正确、请求的数据量是否合理(如果不做限制),想想select *吧。在查询结束上,我这里分了两次查询,就是额外请求一次数据库查询当前符合要求的被分页获取的数据的总数。实现的代码如下:

async function getMatchList(ctx) {let { id, page, limit } = ctx.query;//这里对分组id详细说明,由于前端页面有多个分组,所以这里多一个分组idid = Number(id).toString() == "NaN" ? 1 : Number(id);//分组信息,默认请求第一组的信息page = Number(page).toString() == "NaN" ? 1 : Number(page);//分页,默认请求第一页limit = Number(limit).toString() == "NaN" ? 5 : Number(limit);//分页,默认请求5篇let total = await countByGroup(id);//获取总数//console.log("输出请求参数", id, page, limit);await matchList(id, page, limit).then((data) => {let isTotal = limit * page >= total ? 1 : 0;sendData(ctx, {list: data,isTotal});}).catch((err) => {console.log("输出错误信息:", err);throwError(ctx, -1);});
};

    接下来贴的是与数据库交互的代码,因为我接触thinkphp6比较早,对于thinkphp6的MVC设计模式影响比较深刻,所以一般写后端会自觉将与数据库交互的内容从controller层抽离,这样代码结构也更加清晰,当然你如果喜欢使用ORM架构的话,nodejs是有一个叫Sequelize的第三方依赖包的,但是这个不是很火哈。

//这里是对数据库的连接,每请求一次连接一次数据库?
//不是的,我这里使用的是单例模式;
//构造了一个数据库连接的单例类,如果有连接实例存在直接使用,否则实例化一个数据交互类
const MysqlConnect = require("../config/connect-mysql");
const mysqlDB = new MysqlConnect();
async function countByGroup(group_id) {return new Promise((resolve, reject) => {const sql = `select count(*) sum from match_list where group_id = ${group_id}`;mysqlDB.query(sql, (err, result) => {if (err) {console.log("数据表match查询数据出错:", err);reject(err);} else {resolve(result[0].sum);}})})
}
async function matchInfo() {return new Promise((resolve, reject) => {const sql = "select id,banner,tag from match_group order by id asc";mysqlDB.query(sql, (err, result) => {if (err) {console.log("数据表match查询数据出错:", err);reject();}resolve(result);})});
}
async function matchList(group_id, page, limit) {return new Promise((resolve, reject) => {const sql = `select id,swiperList,title,detail,goods from match_list where group_id = ${group_id} order by id asc ` +`limit ${(page - 1) * limit},${limit}`;mysqlDB.query(sql, (err, result) => {if (err) {console.log("数据表match查询数据出错:", err);reject();}resolve(result);})});
}
module.exports = { matchInfo, matchList,countByGroup };

4.前端的实现与缓存

    可能大家更关心前端怎么实现的吧,前端的实现有一个关键点,就是监听滑动事件,实现上使用的是 @scroll="pageScroll",然后监听event对象里面的3个重要的属性:scrollTopclientHeightscrollHeight。解释这三个参数的含义:举例大盒子顶部的举例、用户视口可视区、具备滑动能力的盒子的总高度(在dom渲染之后这个属性可以自动更新)。

pageScroll(e) {if (e.target.scrollTop + e.target.clientHeight + 20 > e.target.scrollHeight) {//重新发送请求,获取新一批文章this.currentPage++;console.log("输出数据:", this.isTotal);if (!this.isTotal) {showLoadingToast({message: '加载中...',forbidClick: true,loadingType: 'spinner',});this.getMatchList(this.currentTabId, this.currentPage, this.limit);} else {showToast({message: '再怎么找也没有啦~',wordBreak: 'break-word'});}}}

    注意为了能够有效监听到这些参数,需要对css稍微设置一下:

.share-container {background-color: #181818;padding: 0px 10px;padding-bottom: 60px;height: calc(100vh - 90px);//底部留白设计,避免不方便阅读最下面的内容,//同时也能够增加一个没有更多的友好提示overflow: scroll;
}.share-container::-webkit-scrollbar {//这个是为了防止默认滚动条的出现影响了flex布局,直接给隐藏掉display: none;/*Safari and Chrome*/
}

    如今的前端会这些可不够,我这里展示一下期望有的功能:
在这里插入图片描述
    我这里的目标平台是h5(vantUI组件库),如果是uniapp或者小程序的话直接提供了用户滑动触底函数,更简单了,都不用自己监听。上面的效果也有一个是前端的比较常用的——吸顶式布局(position:stikcy,不细说了),在切换tab的时候可以采用缓存,每次切换之后存到localstorage里面,存储方式推荐用JSON.stringify来存,读完之后JSON.parse()转回来,你可能想说要是小程序呢,在uniapp和微信小程序都是提供了缓存读写的,可以查看对应的用法。需要注意的是,为了保证数据安全可以使用一个简单的加密解密比如crypto-js依赖(不够的话再撒点“盐”),能够防止用户直接查看你存储的信息。

5.代码优化方案

    因为我这里写的是毕设的一部分代码,可能在企业应用上看不够严谨,还有很多可以优化的,这里补充一些方案:
(1)在数据加载的时候可以使用骨架屏,因为如果是涉及到图片等加载比较慢容易出现比较严重的闪频,特别是图片内存比较大的时候;
(2)因为这里使用的是分页可滑动,“懒加载”请求出战,因为这里有滑动,“虚拟列表”请求出战;
(3)因为这里有缓存,需要考虑到缓存的有效期问题,如何刷新缓存?当然上面我使用的是切换tab的时候写缓存和读切换目标的缓存,在单纯数据追加上还是说的过去,但是如果信息被修改了就会出现不及时的情况,这里有一个不是很好的方案,全局配置,多加一个网站配置请求,决定是否使用系统缓存的变量,系统资源更新时修改提示放弃使用缓存;
(4)一般列表的图片等可以考虑CDN部署,提均衡多地区的用户体验,也就是让远离服务器的用户能够更快获得响应;
(5)这里的localstorage有些情况下不能使用,可能需要使用redis再来缓存数据,当然这是后端的任务,同时可以利用redis来对请求满足要求的列表数量总数缓存一下,减少额外查库,其实查的是同一个数据。
    最后祝各位找工作的好兄弟们加油,坚持就是顺利!

相关文章:

koa-vue的分页实现

1.引言 最近确实体会到了前端找工作的难处,不过大家还是要稳住心态,毕竟有一些前端大神说的有道理,前端发展了近20年,诞生了很多leader级别的大神,这些大神可能都没有合适的坑位,我们新手入坑自然难一些&am…...

安全开发基础 -- DAST,SAST,IAST简单介绍

安全开发基础-- DAST,SAST,IAST 简介 DAST 动态应用程序安全测试(Dynamic Application Security Testing)技术在测试或运行阶段分析应用程序的动态运行状态。它模拟黑客行为对应用程序进行动态攻击,分析应用程序的反…...

网络安全之暴力破解介绍及暴力破解Tomcat

网络安全之暴力破解介绍及应用场景一、暴力破解介绍1.1 暴力破解介绍1.2 暴力破解应用场景一、暴力破解Tomcat一、暴力破解介绍 1.1 暴力破解介绍 暴力破解字典:https://github.com/k8gege/PasswordDic 1.2 暴力破解应用场景 一、暴力破解Tomcat 登录Tomcat后台&a…...

Elasticsearch:使用 Logstash 构建从 Kafka 到 Elasticsearch 的管道 - Nodejs

在我之前的文章 “Elastic:使用 Kafka 部署 Elastic Stack”,我构建了从 Beats > Kafka > Logstash > Elasticsearch 的管道。在今天的文章中,我将描述从 Nodejs > Kafka > Logstash > Elasticsearch 这样的一个数据流。在…...

记录一次es的性能调优

文章目录es性能调优启用g1垃圾回收器es性能调优 成都的es集群经常出现告警,查看日志发现 [gc][11534155] overhead, spent [38.3s] collecting in the last [38.6s]这是 JVM 垃圾回收过程中的一条日志,表示在最近 38.6 秒内,JVM 进行了一次…...

内核性能评估测试及具体修改操作步骤记录

步骤记录前言一、查看环境配置二、LRU缓存空间调整三、进程扫描时间间隔四、与其他内核对比的工作负载测试(另一个内核的编译)总结前言 记录的相关操作有:查看服务器硬件环境、LRU缓存大小修改、内核命名、内核编译以及进程执行周期的设置。…...

S7-200smart远程无线模拟量信号采集案例

本参考方案使用西门子PLCS7-200SMART 结合无线通讯终端DTD434MC和DTD433F实现 PLC对远端设备模拟量的远程无线输入输出查询控制。所使用到的设备:西门子S7-200smartPLC无线数据终端DTD434MC无线模拟量信号测控终端DTD433F所使用的协议:ModbusRTU协议方案…...

Blender Python材质处理入门

本文介绍在 Blender 中如何使用 Python API 获取材质及其属性。 推荐:用 NSDT场景设计器 快速搭建3D场景。 1、如何获取材质 方法1、 获取当前激活的材质 激活材质是当前在材质槽中选择的材料。 如果你选择一个面,则活动材料将更改为分配给选定面的材质…...

ChatGPT后劲很大,问题也是

ChatGPT亮相即封神,最初的访客是程序员、工程师、AI从业者、投资人,最后是无数懵懂又好奇的普通人:ChatGPT是什么?自己会被ChatGPT取代吗?看待ChatGPT的立场也是两个极端: 快乐,是因为ChatGPT太…...

世界那么大,你哪都别去了,来我带你了解CSS3 (二)

文章目录‍❤️‍🔥CSS文档流‍❤️‍🔥CSS浮动‍❤️‍🔥CSS定位‍❤️‍🔥CSS媒体查询‍❤️‍🔥CSS文档流 文档流是文档中可显示对象在排列时所占用的位置/空间。 例如:块元素自上而下摆放,内…...

2023年再不会Redis,就要被淘汰了

目录专栏导读一、同样是缓存,用map不行吗?二、Redis为什么是单线程的?三、Redis真的是单线程的吗?四、Redis优缺点1、优点2、缺点五、Redis常见业务场景六、Redis常见数据类型1、String2、List3、Hash4、Set5、Zset6、BitMap7、Bi…...

Java SPI机制了解与应用

1. 了解SPI机制 我们在平时学习和工作中总是会听到Java SPI机制,特别是使用第三方框架的时候,那么什么是SP机制呢?SPI 全称 Service Provider Interface,是 Java 提供的一套用来被第三方实现或者扩展的接口,它可以用来…...

vue实现输入框中输完后光标自动跳到下一个输入框中

前言 最近接到这么一个需求,做一个安全码的输入框,限制为6位数,但是每一个写入的值都是一个输入框,共计6个输入框,当前输入框写入值后,光标自动跳到下一个输入框中,删除当前输入框写入的值后再自…...

如何构建 C 语言编译环境?

C语言是一种通用的编程语言,它是由Dennis Ritchie于20世纪70年代初在贝尔实验室开发的。C语言的设计目标是提供一种结构化、高效、可移植的编程语言,以支持系统编程和应用程序开发。C语言广泛用于开发操作系统、网络设备、游戏、嵌入式系统、桌面应用程序…...

电子台账:模板制作之一——列过滤(水平过滤)

1 简介列过滤即水平过滤。一般情况下,企业数据源文件中有很多数据列,其中大部分数据列中的数据对电子台账来说是没有用的。列过滤就是确定企业数据文件的哪几列有用,以及有用的列分别对应到台账(模板)的哪一列。列过滤…...

【java】Java连接mysql数据库及mysql驱动jar包下载和使用

文章目录JDBCJDBC本质:JDBC作用:跟数据库建立连接发送 SQL 语句返回处理结果操作流程和具体的连接步骤如下:操作步骤:需要导入驱动jar包 mysql-connector-java-8.0.22.jar注册驱动获取数据库连接对象 Connection定义sql获取执行sq…...

Mysql八股文

Mysql八股文 数据库的三范式是什么 第一范式:列不可再分第二范式:行可以唯一区分,主键约束第三范式:表的非主属性不能依赖与 其他表的非主属性 外键约束且三大范式是一级一级依赖的,第二范式建立在第一范式上&#x…...

解析Android ANR问题

一、ANR介绍 ANR 由消息处理机制保证,Android 在系统层实现了一套精密的机制来发现 ANR,核心原理是消息调度和超时处理。ANR 机制主体实现在系统层,所有与 ANR 相关的消息,都会经过系统进程system_server调度,具体是ActivityManagerService服务,然后派发到应用进程完成对…...

ESP32设备驱动-MicroSD Card驱动

MicroSD Card驱动 1、SDCard介绍 SD卡是Secure Digital Card卡的简称,直译成汉语就是“安全数字卡”,是由日本松下公司、东芝公司和美国SANDISK公司共同开发研制的全新的存储卡产品。SD存储卡是一个完全开放的标准(系统),多用于MP3、数码摄像机、数码相机、电子图书、AV器…...

XC7K160T-1FBG484I、XC7A100T-2CSG324I FPGA可编程门阵列 PDF规格书

1、XC7K160T-1FBG484I说明:Kintex-7 FPGA有-3、-2、-1、-1L和-2L速度等级,其中-3具有最高的性能。-2L器件被筛选为较低的最大静态功率,并且可以在较低的核心电压下运行,以获得比-2器件更低的动态功率。-2L工业(I)温度器件仅在VCCI…...

JavaSec-RCE

简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性&#xff0c…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

(二)原型模式

原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...

数据库分批入库

今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

C++八股 —— 单例模式

文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性&#xf…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...