提升Element UI分页查询用户体验与交互:实现修改未保存提示
我实现的功能是在 element ui 的分页组件中进行分页查询时,如果当前有未保存的修改数据就提示用户,用户可以选择是否放弃未保存的数据。确认放弃就重新查询数据;选择不放弃,不重新查询,并且显示条数选择框保持原样(选择框中文字与选择列表中选择项),页数跳转也是同样的功能。
例子说明:当我们修改了表单某项数据但未保存时。
更改每页显示条数:我们点击显示条数选择框的 '20条/页',此时会弹出一个提示如图。选择确定就重新查询渲染,未保存数据就丢失了;选择取消的话,不重新查询,并且显示条数保持 '10条/页',打开选择列表也是 '10条/页'。页数跳转:我们点击第二页或者下一页按钮,同样跳出提示如图,选择确定就重新查询渲染,未保存数据就丢失了;选择取消的话,不重新查询,并且仍然选中的是第一页。


动态演示:

首先我们要如何判断用户修改了表单呢?我采用的方法是在查询数据时,深拷贝一份返回的数组数据。然后在分页改变时对比两者。
<el-pagination@size-change="handleSizeChange"@current-change="handlePageChange":current-page.sync="currentPage":page-sizes="[10, 20, 40, 80]":page-size="pageSize":total="totalCount"layout="sizes, prev, pager, next"></el-pagination>
data() {return {currentPage: 1,cachedPage: 1,pageSize: 10,cachedPageSize: 10,totalCount: 0,loading: false, // 是否显示加载中originalData: [],formData: {tableData: [],rules: {}}}},methods: {handleSizeChange(val) {if (!this.isEqual()) {this.$confirm("当前有未保存数据,确定要继续吗?", "提示", {confirmButtonText: "确定",cancelButtonText: "取消",type: "warning"}).then(() => {this.cachedPageSize = val;this.pageSize = val;this.getData();}).catch(() => {this.pageSize = this.cachedPageSize;})} else {this.cachedPageSize = val;this.pageSize = val;this.getData();}},handlePageChange(val) {if (!this.isEqual()) {this.$confirm("当前有未保存数据,确定要继续吗?", "提示", {confirmButtonText: "确定",cancelButtonText: "取消",type: "warning"}).then(() => {this.cachedPage = val;this.currentPage = val;this.getData();}).catch(() => {this.currentPage = this.cachedPage;})} else {this.cachedPage = val;this.currentPage = val;this.getData();}},// 判断表单数据是否改变isEqual() {for (let i in this.formData.tableData) {const obj = this.formData.tableData[i];for (let key in obj)if (obj[key] === "") obj[key] = null; // 属性值为null经过修改再删除会变为"",故将两者看做相等}const newData = this.formData.tableData.map((obj) => {const newObj = Object.assign({}, obj);delete newObj.changed; // changed是告诉后端那些项修改了 对比时要删除return newObj;})return JSON.stringify(newData) === JSON.stringify(this.formData.tableData);},async getData() {const isLoading = this.loading("加载中");const params = {page: this.currentPage,page_size: this.pageSize}const { code, data, count } = await getDataList(params); // 请求列表数据if (code == 200) {this.originalData = JSON.parse(JSON.stringify(data));this.$set(this.formData, "tableData", data);this.totalCount = count;isLoading.close();}}}
这样修改后,页数跳转可以恢复原来的页数,但是 '条/页' 没有恢复。

又从F12里查找对应 dom 元素尝试进行修改,获取 el-pagination 的引用,并且给分页选择框加上类属性 one 来方便获取。
<el-paginationref="pagination"@size-change="handleSizeChange"@current-change="handlePageChange":current-page.sync="currentPage":page-sizes="[10, 20, 40, 80]":page-size="pageSize":total="totalCount"layout="sizes, prev, pager, next":popper-class="'one'"></el-pagination>.catch(() => {this.pageSize = this.cachedPageSize;const pagination = this.$refs.pagination;const select = pagination.$el.querySelector(".one .el-input__inner");select.value = `${this.cachedPageSize}条/页`;const ul = document.querySelector(".el-select-fropdown__list");const fn = () => {const lis = ul.querySelectorAll("li");lis.forEach(li => {li.classList.remove("selected");})const arr = [10, 20, 40, 80];let index = arr.indexOf(this.pageSize);let changedLi = lis[index];changedLi.classList.add("selected");}fn();ul.addEventListener("mouseover", fn);})
结果显示看着是符合的,但是选择 '20条/页' 后取消,应该是 '10条/页' 无法点击,'20条/页' 可以点击,但是结果是 '10条/页' 可以点, '20条/页' 无法点,即虽然改变了样式,但是 element ui 仍然认为我们点击了 '20条/页',现在处于 '20条/页'。

感觉只能去修改 element ui 的源码逻辑了,否则无法满足我的需求;要么就自己写一个分页组件。这时,我突然想到正常的每页显示条数我们每次点击后,不是会自己自动跳转到对应的 '条/页' 吗。于是想到了我直接将对应原来的 '条/页' 的 li 标签触发一次 click ,然后跳过提示弹框与重新请求数据不就好了吗?
data中新增 changedFlag: false,handleSizeChange(val) {if (!this.changedFlag && !this.isEqual()) {this.$confirm("当前有未保存数据,确定要继续吗?", "提示", {confirmButtonText: "确定",cancelButtonText: "取消",type: "warning"}).then(() => {this.cachedPageSize = valthis.pageSize = valthis.getData()}).catch(() => {this.pageSize = this.cachedPageSize;const ul = document.querySelector(".one .el-select-fropdown__list");const lis = ul.querySelectorAll("li");const arr = [10, 20, 40, 80];let index = arr.indexOf(this.pageSize);let changedLi = lis[index];this.changedFlag = true;changedLi.click();})} else { // 判断是否是changedLi触发clickif (this.cachedPageSize == val) {this.changedFlag = false;this.pageSize = val}else {this.changedFlag = false;this.cachedPageSize = val;this.pageSize = val;this.getData();}}},
最终达到想要的效果:

相关文章:
提升Element UI分页查询用户体验与交互:实现修改未保存提示
我实现的功能是在 element ui 的分页组件中进行分页查询时,如果当前有未保存的修改数据就提示用户,用户可以选择是否放弃未保存的数据。确认放弃就重新查询数据;选择不放弃,不重新查询,并且显示条数选择框保持原样&…...
UML-时序图
目录 时序图 时序图构成: 对象: 消息: 生命线(激活): 活动条: 时序图举例: 时序图 时序图也叫顺序图、序列图. 时序图描述按照时间的先后顺序对象之间的动作过程,是由生命线和消息组成 时序图构成: 对象: 对象是类的实例,对象是通过类来创建的&…...
Seata - 入门笔记
1、事务 访问并可能更新数据库中数据库中各种数据线的一个程序执行单元 原子性:事务是一个不可分割的工作单位,一个事务要么都做要么都不做 一致性:必须是使数据库从一个一致性到另一个一致性的状态,中间状态不能被观察到 隔离…...
springboot使用aop排除某些方法,更新从另外一张表,从另外一张表批量插入
AOP 在Spring Boot中使用AOP时,如果想要排除某些方法不被切面所影响,可以通过使用切面表达式中的!within关键字来实现。以下是一个示例: Aspect Component public class MyAspect {Before("execution(* com.example.service.*.*(..)) …...
Go 语言面试题(二):实现原理
文章目录 Q1 init() 函数是什么时候执行的?Q2 Go 语言的局部变量分配在栈上还是堆上?Q3 2 个 interface 可以比较吗?Q4 两个 nil 可能不相等吗?Q5 简述 Go 语言GC(垃圾回收)的工作原理Q6 函数返回局部变量的指针是否安全ÿ…...
SAP MM学习笔记16-在库品目评价
在库品目评价是指评估物料。具体比如物料价格,数量,保管场所等发生变化的时候,判断是否发生了变化,要不要生成 FI票,用哪个FI科目来进行管理等内容就叫在库品目评价。 在库品目评价有很多层级,这里先讲3兄弟…...
Azure通过自动化账户实现对资源变更
Azure通过自动化账户实现对资源变更 创建一个自动化账户第一种方式 添加凭据(有更改资源权限的账户,没有auth认证情况)创建一个Runbook,测试修改 AnalysisServices 定价层设置定时任务:开始定时任务: 第二种…...
使用luarocks安装cjson并使用cjson
1.luarocks安装 wget https://luarocks.org/releases/luarocks-3.3.1.tar.gz --no-check-certificatels -lrthtar -xvf luarocks-3.3.1.tar.gz mv luarocks-3.3.1 /usr/local/cd /usr/local/luarocks-3.3.1/./configure --prefix/usr/local/luarocks-3.3.1 vim /etc/profilePAT…...
【已解决】mac端 sourceTree 解决remote: HTTP Basic: Access denied报错
又是在一次使用sourcetree拉取或者提交代码时候,遇到了sourcetree报错; 排查了一会,比如查看了SSH keys是否有问题、是否与sourcetree账户状态有问题等等,最终才发现并解决问题 原因: 因为之前公司要求企业gitlab中…...
javaee dom4j读取xml文件
引入jar包 dom4j-1.6.1.jar 创建xml文件 <?xml version"1.0" encoding"UTF-8"?> <books><book id"1"><title ID"t1">背影</title><price>88</price><author>三毛</author>…...
各类背包问题
1、0-1背包问题 (1)用二维数组动态规划 #include<bits/stdc.h> using namespace std; int m,n; int w[50],c[50]; int dp[210][210]; int main() {cin>>m>>n;for(int i1;i<n;i){cin>>w[i]>>c[i];}for(int i1;i<n;…...
《练习100》91~95
题目91 # 自动生成字符串 # a [小马,小羊,小鹿] # b [草地上,电影院,家里] # c [看电影,听音乐,吃晚饭] # 随机生成三个0~2的数字,若是1,0,2 ,则输出: 小羊在草地上吃晚饭 import random a [小马,小羊,小鹿] b […...
3.6 Spring MVC文件上传
1. 文件上传到本地 实现方式 Spring MVC使用commons-fileupload实现文件上传,注意事项如下: l HTTP请求方法是POST。 l HTTP请求头的Content-Type是multipart/form-data。 SpringMVC配置 配置commons-fileupload插件的文件上传解析器CommonsMultip…...
# X11、Xlib、XFree86、Xorg、GTK、Qt、Gnome和KDE之间的关系
X11、Xlib、XFree86、Xorg、GTK、Qt、Gnome和KDE之间的关系 很多人对于他们是啥是傻傻分不清的,我做了个表格供大家参考。 摘抄: X11是X Window System Protocol, Version 11(RFC1013),是X server和X client之间的通…...
rknn3588如何查看npu使用情况
cat /sys/kernel/debug/rknpu/load在Linux中,你可以使用一些工具和命令来绘制某一进程的实时内存折线图。一个常用的工具是gnuplot,它可以用来绘制各种图表,包括折线图。 首先,你需要收集进程的实时内存数据。你可以使用pidstat命…...
“Can‘t open perl script configure : No such file or directory”的解决办法
编译OpenSSL的时候执行到 perl configure 时提示找不到configure, 然后在网上搜了搜,大家给的解决办法一般都是说设置环境变量或者指定configure路径再执行;我试了都不行, 最后我把perl卸了重装就正常了; 然后我换了…...
ChatGLM2-6B在windows下的部署
2023-08-10 ChatGLM2-6B在windows下的部署 一、部署环境 1、Windows 10 专业版, 64位,版本号:22H2,内存:32GB 2、已安装CUDA11.3 3、已安装Anaconda3 64bit版本 4、有显卡NVIDIA GeForce RTX 3060 Laptop GPU …...
nodejs+vue+elementui学生档案信息管理系统_06bg9
利用计算机网络的便利,开发一套基于nodejs的大学生信息管理系统,将会给人们的生活带来更多的便利,而且在经济效益上,也会有很大的便利!这可以节省大量的时间和金钱。学生信息管理系统是学校不可缺少的一个环节,其内容直…...
Nginx location
location块是nginx配置文件中,配置在http块中的server块中,匹配的是uri location匹配uri的方式 : 精确匹配: location /[ ...} 正则匹配: location - /{ ...} 一般匹配: location /{ ....} 匹配的规则: :精确匹…...
数据库字段命名导致的SQL报错
1.表设计 create table variables (id bigint not null comment 主键,business_key varchar(128) null comment 业务key,key varchar(128) null comment Map中的key,value varchar(255) null comment…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...
AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...
