测试开发【Mock平台】09开发:项目管理(五)搜索、删除和Table优化

【Mock平台】为系列测试开发教程,从0到1编码带你一步步使用Spring Boot 和 Antd React框架完成搭建一个测试工具平台,希望作为一个实战项目对各位的测试开发学习之路有帮助,大奇一个专注测试技术干货原创与分享的家伙。

Mock平台系统项目基本配置,我们已经完成了展示,增加、修改,这个模块的进度其实已经差不多80%了,在本分享中将收下尾,为数据表格配置分页,实现简单搜索功能,以及删除功能,还会掌握如何自定义格式化列数据。

1.优化Table展示

表格形式的数据,一般未来累计超过20条的非常建议为其增加分页功能,在antd中Table组件有自带这个配置,但在之前的逻辑实现中特意关掉了,内部其实嵌套的也是Pagination分页组件,下边将详细演示内嵌和独立使用两种形式。

1.1 Pagination组件

分页组件在数据量大且加载/渲染所有数据将花费很多时间时,可以利用分页器组件进行页码浏览,要使用它需要导入组件 import{ Pagination }from'antd';其中基础配置属性** **total总数量,会根每页条数 pageSize(默认是10条)计算多少页,另外还有一个重要方法 onChange指页码或 pageSize 改变时回调,function(page, pageSize)参数是改变后的页码及每页条数。

参考官方例子给项目列表Table下方增加此组件,为了先做个演示测试,数据固定给50条,并主动开启

  • showSizeChanger 展示 pageSize 切换器,组件默认 total 大于 50 时为 true
  • pageSizeOptions 数组 指定每页可以显示多少条
import{ Pagination }from'antd';/* 分页相关 */
const pageChange = (page, pageSize) => {console.log(`分页变化值 Page:${page}, PageSize:${pageSize}`);
}...省略...
</Table>
<br/>  
<Paginationtotal={100}onChange={pageChange}showSizeChanger={true}pageSizeOptions={[5,10,20,30,50]}
/>

当点击切换页,下拉选择改变每页显示的数量时候,可以直观的看到的两个参数数值的变化,如下图:
image.png

因此在实现项目表格分页上,只需要在onChange里请求之前文章后服务分页查询接口,并将统计的总数动态赋值,就能实现优化改造。这里参考代码有些注意的地方:

  • 不要忘记server.js 的接口配置;
export async function searchProducts(params) {return request('/api/mock/project/search', {method: 'GET',params});
}
  • 定义了些中间变量存储各类数据;
  • 换了fetchData方法函数替代原有请求列表,并且是参数化请求,避免React闭包问题;
  • 列表查询接口还有一个项目名称模糊查询字段,组合请求参数时不要忘记;
  // const {data:useProjectList, error, loading, run: reloadProjectList} = useRequest(getProductList);const [data, setData] = useState();const [loading, setLoading] = useState(false);const [current, setCurrent] = useState(1);const [pageSize, setPageSize] = useState(10);const [total, setTotal] = useState();const fetchData = (name, current, pageSize) => {setLoading(true);searchProducts({name:name, current:current, pageSize: pageSize}).then(reps => {setData(reps.data);setTotal(reps.total);setLoading(false);});};/* 分页相关 */const pageChange = (page, pageSize) => {setCurrent(page);setPageSize(pageSize);fetchData('', page, pageSize);}// 页面首次请求项目列表数据初始化useEffect(() => {fetchData('', current, pageSize);}, []);
  • 对原有数据来要做变方法和变量替换,核心部分如下,其他根据IDE提示解决或者参考源代码;
<Tableloading={loading}rowKey="id"pagination={false}columns={projectColumns}dataSource={data}
/>
<br/>
<Paginationtotal={total}current={current}pageSize={pageSize}onChange={pageChange}showSizeChanger={true}pageSizeOptions={[5,10,20,30,50]}
/>

代码开发调试效果如演示GIF

这里其实有个问题,就是当切换每页数量时候,当前选中页面还是之前的,如果条数从小条切到大,就有当前页数超出新的页数量总数情况,解决办法如果pageSize有变更,初始化默认页为第一页。

const pageChange = (page, size) => {// 如果改变了size 将其page设置为第一页let tmpPage = 1;if(size !== pageSize){tmpPage = 1} else {tmpPage = page;}setCurrent(tmpPage);setPageSize(size);fetchData('', tmpPage, size);}

1.2 Table自带分页

对于Table组件是有内置的分页功能,其实也就是Pagination组件,并对其做了封装得以使用更简单

https://ant.design/components/table-cn/#components-table-demo-ajax

image.png

有了上边1.1基础,改造起来就简单多了,只需将Pagination部分内容以JSON赋值方式赋值给Table中的pagination即可。

<Tableloading={loading}rowKey="id"pagination={{total:total,current:current,pageSize:pageSize,onChange: pageChange,showSizeChanger:true,pageSizeOptions:[5,10,20,30,50]}}columns={projectColumns}dataSource={data}
/>

可以看到包括样式在内,自动展示了分页,并且尝试测试切换也均正常,不过我的例子中单独的变量定义的有点多,你们可以尝试参考官方Table远程加载数据例子再优化一版。
image.png

1.3 列表数据格式化

在表格数据展示中其中我们可以看到类型一栏显示还是数据库里的字段,所以这里说明下如何实现格式展示,方法和操作相似,使用 render 自定义请求一个方法,此方法根据类型判断返回相应文字和组件。

const formatType = (txtType) =>{if (txtType === 'public') {return <Tag>公共项目</Tag>} else if (txtType === 'private') {return <Tag>私有项目</Tag>} else {return <Tag>未知类型</Tag>}}// 表单列const projectColumns = [...{dataIndex:"type",title:"类型",render: (text, _) => (formatType(text)),},...]

代码中实现的是将英文关键词转换成对应的中文进行显示,并用Tag标签包裹。
image.png

之后其他想做数据格式化展示,或多列合并一条,再或根据不同值展示不同样式等等,都可以使用此方法,当然后边有一种 ProTable 高级表格的时候,它提供多种类型数据展示提供了内置格式化,后续用到再进行详细说明。

2.搜索功能

在优化Table显示需求中替换带分页查询的接口时,我们预留的一个searchName 参数,对于多数据的展示如果能有个主要信息的搜索功能才比较完美,这里利用 Grid栅格Form行内表单 组件实现。

https://ant.design/components/grid-cn/
https://ant.design/components/form-cn/#components-form-demo-layout

Grid 用于布局,基于行(row)和列(col)来定义信息区块的外部框架,笔者因为对CSS不熟,不能熟练的用于DIV做一些样式布局,所以就常用栅格来控制行和列来达到想要的区域块布局效果。
**Form **行内是表单布局一种,一行的显示样式,常用于搜索、快捷编辑等场景。
参考两个组件官方API说明,最终我们要实现如下的页面效果:
image.png

这里由于之前表单的操作已经实战过Form的用法,所以就直接给出了参考代码,其中style是简单样式,实现右边6个栅格区域按钮靠右对齐。

 <Row><Col span={18}><Form layout="inline"onFinish={...todo实现提交代码...}><Form.Item name="searchName" label="项目名称"><Input></Input></Form.Item><Form.Item><Button htmlType="submit">搜索</Button></Form.Item></Form></Col><Col span={6}><ButtononClick={addAction}type="primary"style={{marginBottom: 16,marginRight: 20,float: "right"}}>项目添加</Button></Col>
</Row>

最后补充下表单提交的实现代码

// 搜索
const onSearch = (values) => {fetchData(values.searchName, current, pageSize)
};// return 内表单修改部分
<Form layout="inline"onFinish={onSearch}
>

输入一个关键点击搜索测试一下OK,但参考代码到这里会有交互缺陷,如果给定的关键词搜索的结果也是多页,那么我在切换页面或者页数量的时候,由于之前代码name都写死的空值,所以又会变成全量查询,这个问题的优化留个思考题吧,看看是你会怎么做?
image.png
ps:项目源代码中有我的优化答案可以进行参考

3.项目删除功能

实现完了编辑功能,操作列里还有一个删除操作,一般为了防止删除这种危险动作是误操作,将会用到上一篇中的确认对话框知识点,不过这里将用到官方例子里的 showPromiseConfirm即确定按钮触发会有等待,明确得到返回成功后关闭对话框。

3.1 删除接口

此接口没在之前的 Mock平台-05开发:项目管理(一)后端接口 准备好,需要现实现,MVC全部的代码如下,不再赘述Springboot API实现知识点,不会或者忘记的翻下系列第五篇回看下。这里需要特别强调下,这里删除是个软删除,所以要对数据库表增加一个字段 is_del (0-默认,1-删除)来做标记,实际删除就是更新此字段为删除状态。

MockProjectMapper.java

/**
* 删除项目,软删除标记is_del=1
* @param id
* @return 影响数量 更新成功默认1
*/
@Update({"UPDATE mock_project SET mp_state=1 WHERE mp_id=#{id}"})
Boolean removeProject(Integer id);

MockProjectService.java

RespResult removeMockProject(Integer id);

MockProjectServiceImpl.java

@Override
public RespResult removeMockProject(Integer id) {Boolean markResult = mockProjectMapper.removeProject(id);if (markResult){return RespResult.success();}return RespResult.failure(RespCode.DATA_REMOVE_ERROR);
}

MockProjectController.java

@PostMapping(value = "/project/remove")
public RespResult removeProject(@Param("id") Integer id){return mockProjectService.removeMockProject(id);
}

3.2 删除交互

对于前度删除功能交互的实现,先按照流程先定义服务请求接口

export async function removeProduct(id) {return request('/api/mock/project/remove?id='+id, {method: 'POST'});
}

动态生成确认对话框需要导入Modal组件里的子项 confirm 主要的三个属性和两个方法

  • title 对话显示的标题
  • icon 引用icon图标组件
  • content 详细的内容,支持ReactNode
  • onOk 点击确定按钮触发
  • onCancel 点击取消按钮触发,不做逻辑处理默认为关闭对话框
const { confirm } = Modal;
import { removeProduct } from "@/pages/Project/service";
....省略...// 删除操作
const deleteConfirmWithPromise = (record) => {confirm({title: '删除确认?',icon: <ExclamationCircleOutlined />,content: `确定要删除【${record?.name}】吗?`,async onOk() {const result = await removeProduct(record.id);if(result.success){message.success('删除项目成功!');// 成功后刷新fetchData(sName, current, pageSize);} else{message.error('删除项目失败!');}},onCancel() {},});};

表格操作栏删除按钮添加deleteConfirmWithPromise并把所在行数据传过去。

{dataIndex:"option",title:"操作",render: (text, record) => (<Space><a onClick={()=>editAction(record)}>编辑</a>
+    <a onClick={()=>deleteConfirmWithPromise(record)}>删除</a></Space>
),},

按例重启前后端服务,进行删除取消/确认/删除成功页面刷新的用例测试。

花了大篇幅在比较简单需求的项目管理上,是为务牢基础为后边核心逻辑更轻松,另外学习是一个过程,尤其是基础知识薄弱的,一定不要是看会,而是动手实战,进而有自己的想法和移花接木的本领,最终从务实角度来讲能在实际工作中业务上应用,哪怕是务虚为了KPI、“钱途“也要做点什么。

最后预告系列分享开发实战部分终于要进入核心部分的实现,比如分类Tree,接口管理,Mock拦截等实战内容,欢迎长期关注哦!

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

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

相关文章

数据集学习笔记(六):目标检测和图像分割标注软件介绍和使用,并转换成YOLO系列可使用的数据集格式

文章目录 一、目标检测1.1 labelImg1.2 介绍1.3 安装1.4 使用1.5 转换1.6 验证 二、图像分割2.1 labelme2.2 介绍2.3 安装2.4 使用2.5 转换2.6 验证 一、目标检测 1.1 labelImg 1.2 介绍 labelImg是一个开源的图像标注工具&#xff0c;用于创建图像标注数据集。它提供了一个…

iOS 设置下载部分文件,如何获取完整文件的大小

在视频的需求中&#xff0c;遇到这样一个需求&#xff0c;播放一视频的时候&#xff0c;要预下载 后面10条视频&#xff0c;但是只下载后面十条视频的前面1M 实现方法 1 创建请求时设置cacheLength resource [[IdiotResource alloc] init];resource.requestURL task.request…

不同路径 II【动态规划】

不同路径 II 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish”&#xff09;。 现在考虑网格中有障碍物。那么从左上…

深入解析即时通讯App开发中的关键技术

即时通讯App开发在现代社交和通信领域中扮演着重要的角色。随着移动设备的普及和网络的高速发展&#xff0c;人们对即时通讯工具的需求不断增加。本篇文章将深入探讨即时通讯App开发中的关键技术&#xff0c;帮助读者了解该领域的最新动态和技术趋势。 基础架构和通信协议 现…

阻塞/非阻塞、同步/异步(网络IO)

1.阻塞/非阻塞、同步/异步(网络IO) 【思考】典型的一次 IO 的两个阶段是什么&#xff1f; 数据就绪 和 数据读写 数据就绪 &#xff1a;根据系统 IO 操作的就绪状态 阻塞 非阻塞 数据读写 &#xff1a;根据应用程序和内核的交互方式 同步 异步 陈硕&#xff1a;在处理 IO …

ISP——3A算法

目录 前沿一. 自动曝光AE1.1. 自动曝光1.2. 18%灰1.3. 测光区域1.4. 摄影曝光加法系统1.5. AE算法1.5.1. 考虑事项1.5.2. AE实现过程 1.6. AE算法 二. 自动对焦AF2.1. 什么是自动对焦2.2. 图像清晰度评价方法2.2.1. Brenner 梯度函数2.2.2. Tenengrad 梯度函数2.2.3. Laplacian…

1.12 进程注入ShellCode套接字

在笔者前几篇文章中我们一直在探讨如何利用Metasploit这个渗透工具生成ShellCode以及如何将ShellCode注入到特定进程内&#xff0c;本章我们将自己实现一个正向ShellCodeShell&#xff0c;当进程被注入后&#xff0c;则我们可以通过利用NC等工具连接到被注入进程内&#xff0c;…

【vue】this.$nextTick解决this.$refs undefined的问题

说明 1、发邮件页面分成两个部分&#xff1a;模态框页面&#xff08;头部和底部&#xff09;和form页面&#xff08;操作按钮&#xff09; 2、点击回复按钮&#xff0c;要将发件人信息带到模态框页面&#xff0c;给定默认值且禁止收件人下拉选择&#xff08;多个邮箱&#xff…

Windows Update Blocker,windows系统关闭自动更新工具

今天打开电脑发现系统又自动更新了 这一天天更新真的太烦了 然后我从网上找到一个工具 可以自由开启和关闭系统自动更新 这里分享一下网址&#xff1a;https://www.filehorse.com/download-windows-update-blocker/ 若网址失效&#xff0c;蓝奏云盘链接 https://wwgw.lanzouc.c…

归并排序的详解!

本文旨在讲解归并排序的实现&#xff08;递归及非递归&#xff09;搬好小板凳&#xff0c;干货来了&#xff01; 前序&#xff1a; 在介绍归并排序之前&#xff0c;需要给大家介绍的是什么是归并&#xff0c;归并操作&#xff0c;也叫归并算法&#xff0c;指的是将两个顺序序列…

lv3 嵌入式开发-3 linux shell命令(文件搜索、文件处理、压缩)

目录 1 查看文件相关命令 1.1 常用命令 1.2 硬链接和软链接 2 文件搜索相关命令 2.1 查找文件命令 2.2 查找文件内容命令 2.3 其他相关命令 3 文件处理相关命令 3.1 cut 3.2 sed 过滤 3.3 awk 匹配 4 解压缩相关命令 4.1 解压缩文件的意义 4.2 解压缩相关命令 1 …

大学物理 之 安培环路定理

文章目录 前言什么是安培环路定理安培环路定理有什么作用 深入了解深入学习 前言 什么是安培环路定理 安培环路定理的物理意义在于描述了电流和磁场之间的相互作用&#xff0c;以及如何在一个封闭的回路中分析这种相互作用。 简单的来说 , 用环路定理来解决在磁场中B对任意封…

[管理与领导-65]:IT基层管理者 - 辅助技能 - 4- 职业发展规划 - 乌卡时代(VUCA )

前言&#xff1a; 大多数IT人&#xff0c;很勤奋&#xff0c;但都没有职业规划&#xff0c;被工作驱动着前行&#xff0c;然而&#xff0c;作为管理者&#xff0c;你就不能没有职业规划思维&#xff0c;因为你代表一个团队&#xff0c;你的思维决定了一个团队的思维。本文探讨…

redis实战-实现优惠券秒杀解决超卖问题

全局唯一ID 唯一ID的必要性 每个店铺都可以发布优惠券&#xff1a; 当用户抢购时&#xff0c;就会生成订单并保存到tb_voucher_order这张表中&#xff0c;而订单表如果使用数据库自增ID就存在一些问题&#xff1a; id的规律性太明显&#xff0c;容易被用户根据id的间隔来猜测…

如何实现的手机实景自动直播,都有哪些功能呢?

手机实景自动直播最近真的太火了&#xff0c;全程只需要一部手机&#xff0c;就能完成24小时直播带货&#xff0c;不需要真人出镜&#xff0c;不需要场地&#xff0c;不需要搭建直播间&#xff0c;只需要一部手机就可以了。真人语音讲解&#xff0c;真人智能回复&#xff0c;实…

C#-单例模式

文章目录 单例模式的概述为什么会有单例模式如何创建单例模式1、首先要保证&#xff0c;该对象 有且仅有一个2、其次&#xff0c;需要让外部能够获取到这个对象 示例通过 属性 获取单例 单例模式的概述 总结来说&#xff1a; 单例 就是只有 一个实例对象。 模式 说的是设计模式…

《Go 语言第一课》课程学习笔记(十二)

函数 Go 函数与函数声明 在 Go 语言中&#xff0c;函数是唯一一种基于特定输入&#xff0c;实现特定任务并可返回任务执行结果的代码块&#xff08;Go 语言中的方法本质上也是函数&#xff09;。在 Go 中&#xff0c;我们定义一个函数的最常用方式就是使用函数声明。 第一部…

Mybatis学习|注解开发、lombok

1.使用注解开发 无需再编写相应的Mapper.xml文件&#xff0c;直接将sql用注解的形式写在Mapper接口的对应方法上即可。 然后因为没有xml文件,所以要在mybatis-config.xml核心配置文件中注册这个Mapper接口&#xff0c;而不用去注册之前的Mapper.xml&#xff0c;这里其实如果用…

QT listWidget 中实现元素的自由拖拽

QListWIdget中拖拽元素移动 setMovement(QListView::Movement::Free);setDragEnabled(true); setDragDropMode(DragDropMode::DragDrop); setDefaultDropAction(Qt::DropAction::MoveAction);

nginx-反向代理缓存

反向代理缓存相当于自动化动静分离。 将上游服务器的资源缓存到nginx本地&#xff0c;当下次再有相同的资源请求时&#xff0c;直接讲nginx缓存的资源返回给客户端。 本地缓存资源有一个过期时间&#xff0c;当超过过期时间&#xff0c;则重新向上游服务器重新请求获取资源。…