前端分页:非当前页进行表单验证

概览

对于大数据量批量导入,渲染到表格的场景中,可能会造成浏览器崩溃,此时前端分页可以很好地解决这个问题,但是组件库自带的表单验证通常只能进行当前页的验证,如何实现对全量数据的表单验证呢?此篇文章来梳理解决

一. 完整代码示例

<template><el-form :model="dataForm" ref="ruleForm" label-width="100px" class="demo-ruleForm"><table border><thead><tr><th>#</th><th><span class="requiredLabel">姓名</span></th><th><span class="requiredLabel">年龄</span></th></tr></thead><tbody><tr v-for="(item, index) in currentPageData" :key="index"><td>{{ index + (currentPage - 1) * pageSize + 1 }}</td><td><el-form-item:prop="'details.' + (index + (currentPage - 1) * pageSize) + '.name'":rules="rules.name":key="'details.' + (index + (currentPage - 1) * pageSize) + '.name'"><el-inputv-model="item.name"placeholder="请输入姓名"clearable></el-input></el-form-item></td><td><el-form-item:prop="'details.' + (index + (currentPage - 1) * pageSize) + '.age'":rules="rules.age":key="'details.' + (index + (currentPage - 1) * pageSize) + '.age'"><el-inputv-model="item.age"placeholder="请输入年龄"clearabletype="number"></el-input></el-form-item></td></tr></tbody></table><div><el-button @click="prevPage" :disabled="currentPage === 1">上一页</el-button><el-button @click="nextPage" :disabled="currentPage === Math.ceil(totalCount / pageSize)">下一页</el-button></div><el-button @click="handleCreate">立即创建</el-button></el-form>
</template><script setup>import { reactive, ref, computed,nextTick } from 'vue';import AsyncValidator from 'async-validator';const dataForm = reactive({details: Array.from({ length: 20 }, (_, i) => ({ name: '', age: null })),});const rules = {name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],age: [{ required: true, message: '请输入年龄', trigger: 'blur'}],};const currentPage = ref(1);const pageSize = ref(5);const totalCount = ref(dataForm.details.length);const ruleForm = ref(null);const currentPageData = computed(() => {const start = (currentPage.value - 1) * pageSize.value;const end = start + pageSize.value;return dataForm.details.slice(start, end);});const schemaValidator = (item) => {const schema = new AsyncValidator(rules);return schema.validate(item, { firstFields: true }).then((res) => {console.log(res, 'then res');return true;}).catch(({ errors }) => {return false;});};const handleCreate = async () => {const fields = {name: {rules,validate: schemaValidator,},};for (let i = 1; i < dataForm.details.length; i++) {const item = dataForm.details[i];let allValid = true; // 假设当前 item 的所有字段都有效for (const key in item) {if (fields[key]) {try {if (!(await fields[key].validate(item))) {currentPage.value = Math.floor((i+1)/pageSize.value) + 1;allValid = false;break; // 跳出内层循环}} catch (error) {allValid = false;break; // 跳出内层循环,并在发生错误时也视为验证失败}}}if (!allValid) {break; // 跳出外层循环}}await nextTick();ruleForm.value.validate((valid) => {console.log(valid,'valid123456')if (valid) {console.log('表单验证通过');// 处理表单提交逻辑} else {console.log('表单验证失败');return false;}});};const prevPage = () => {if (currentPage.value > 1) currentPage.value--;};const nextPage = () => {if (currentPage.value < Math.ceil(totalCount.value / pageSize.value)) currentPage.value++;};
</script><style lang="scss" scoped>/* 添加您的样式 */
</style>

可以直观运行感受下

二. 解决思路梳理

整体实现思路:

  1. 校验时,获取第一个不符合校验项的下标;
  2. 根据下标,找到对应不符合项的页码;
  3. 切换当前页码至不符合项的页码;
  4. 进行表单验证

此时的难点在于如何获取不符合项的页码

需要借助async-validator库的使用,这里着重讲下,相关代码如下

  import AsyncValidator from 'async-validator';const rules = {name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],age: [{ required: true, message: '请输入年龄', trigger: 'blur'}],};const schemaValidator = (item) => {const schema = new AsyncValidator(rules);return schema.validate(item, { firstFields: true }).then((res) => {console.log(res, 'then res');return true;}).catch(({ errors }) => {return false;});};const handleCreate = async () => {const fields = {name: {rules,validate: schemaValidator,},};for (let i = 1; i < dataForm.details.length; i++) {const item = dataForm.details[i];let allValid = true; // 假设当前 item 的所有字段都有效for (const key in item) {if (fields[key]) {try {if (!(await fields[key].validate(item))) {currentPage.value = Math.floor((i+1)/pageSize.value) + 1;allValid = false;break; // 跳出内层循环}} catch (error) {allValid = false;break; // 跳出内层循环,并在发生错误时也视为验证失败}}}if (!allValid) {break; // 跳出外层循环}}await nextTick();ruleForm.value.validate((valid) => {if (valid) {console.log('表单验证通过');// 处理表单提交逻辑} else {console.log('表单验证失败');return false;}});};

需要进行两层的循环遍历,第一层是全部的数据,第二层是校验规则,在全部的数据里面根据校验规则进行筛选,主要如下

  1. 遍历全部数据,根据校验规则,获取到全部数据中子项中有校验的字段;
  2. 调用validate进行校验,获取全部数据中子项中第一个不符合校验的下标值;

async-validator的作用主要是什么?

可以根据校验规则,来进行是否符合校验判断,并返回布尔值。

三. 循环中退出

有两种写法:
第一种:增加变量,break退出

const getWrapperInnerData = async () => {for (let i = 0; i < propsDetails.length; i++) {const item = propsDetails[i];let valid = true;for (const key in item) {if (fields[key]) {if (!(await validateName(item.index).catch(() => false))) {console.log(item.index);valid = false;break;}}}if (!valid) {break;}}
};

第二种:return 退出

const getWrapperInnerData = async () => {for (let i = 0; i < propsDetails.length; i++) {const item = propsDetails[i];for (const key in item) {if (fields[key]) {if (!(await validateName(item.index).catch(() => false))) {console.log(item.index);return false;}}}}
};

第一种写法

在第一种写法中,通过引入一个valid变量来跟踪当前项的校验状态,并在发现不符合项时通过break语句退出内层循环。然后,在外层循环中检查valid变量的值,如果为false,则通过另一个break语句退出外层循环。这种方式需要额外的变量和嵌套的控制流语句来管理循环的退出。

第二种写法

第二种写法则更为直接。在内层循环中,一旦发现不符合校验项,就立即通过return false语句退出整个函数。这种方式省去了额外的变量和复杂的控制流结构,使得代码更加简洁明了。同时,由于return语句会立即终止函数的执行,因此也确保了函数在找到第一个不符合项后不会继续处理剩余的项。

此外,第二种写法还隐含了一个优势:它清晰地表达了函数的意图——即校验过程中一旦发现不符合项就立即终止,并返回一个表示失败的值(在这里是false)。这种明确的返回值使得函数的调用者能够更容易地理解函数的执行结果。

因此,从简洁性和明确性的角度来看,第二种写法是更优的选择。它不仅能够实现所需的功能,而且代码更加清晰易懂。

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

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

相关文章

C++基于opencv的视频质量检测--画面冻结检测

文章目录 0.引言1. 原始代码分析2. 优化方案3. 优化后的代码4. 代码详细解读 0.引言 视频质量画面冻结检测已在C基于opencv4的视频质量检测中有所介绍&#xff0c;本文将详细介绍其优化版本。 1. 原始代码分析 图像抖动检测的原始代码&#xff1a; bool ScreenFreezeDetect…

AI驱动的低代码未来:加速应用开发的智能解决方案

引言 随着数字化转型的浪潮席卷全球&#xff0c;企业对快速构建应用程序的需求愈发强烈。然而&#xff0c;传统的软件开发周期冗长、成本高昂&#xff0c;往往无法满足快速变化的市场需求。在此背景下&#xff0c;低代码平台逐渐成为开发者和企业的优选方案&#xff0c;以其“低…

【蓝桥杯选拔赛真题77】python计算小球 第十五届青少年组蓝桥杯python选拔赛真题 算法思维真题解析

目录 python计算小球 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python计算小球 第十五届蓝桥杯青少年组python比赛选拔赛真题 一、题目要…

架构师备考-非关系型数据库

基础理论 CAP 理论 C&#xff08;Consistency&#xff09;一致性。一致性是指更新操作成功并返回客户端完成后&#xff0c;所有的节点在同一时间的数据完全一致&#xff0c;与ACID 的 C 完全不同。A &#xff08;Availability&#xff09;可用性。可用性是指服务一直可用&…

内网渗透-初探域渗透

文章目录 环境域信息收集系统基本信息网络信息域控主机信息根据ip查主机名用户信息权限提升网络探针系统命令nbtscanfscannishang 凭据收集 域渗透实战凭据收集(重点)mimikatzProcdumpPwdumpSAMInsidekrbtgt用户hash hash破解解决无法获取明文的问题明文口令传递IPC连接atschta…

DispatchingController

目录 1、 DispatchingController 1.1、 //维修派工 1.2、 ClearDispatching 1.3、 查询派工结算方式金额 DispatchingController using QXQPS.Models; using QXQPS.Vo; using System; using System.Collections.Generic; using System.Linq; using System.Web; …

windows录屏软件工具推荐!!

如今&#xff0c;科技的进步&#xff0c;互联网的普及&#xff0c;使我们的生活越来越便利&#xff0c;录屏工具的出现&#xff0c;大大提高我们的工作效率。如果你经常需要录制屏幕上的内容&#xff0c;比如制作教学视频、游戏实况记录、演示文稿等等&#xff0c;那这几款软件…

【ChatGPT】如何通过反向思维改进Prompt的编写

如何通过反向思维改进Prompt的编写 在与ChatGPT互动的过程中&#xff0c;编写高质量的Prompt&#xff08;提示词&#xff09;是确保生成内容准确且符合需求的关键。反向思维&#xff08;Reverse Thinking&#xff09;是一种创造性思维方法&#xff0c;通过从结果或目标出发&am…

【病毒分析】从无解到破解:Mallox家族linux版本的分析以及解密器的制作

1.背景 Mallox勒索软件首次出现于2021年5月&#xff0c;并在2021年10月扩展到中国市场。截至2024年&#xff0c;它仍然活跃。Mallox通过加密受害者文件并要求支付赎金来恢复数据&#xff0c;使用唯一的加密密钥加密文件&#xff0c;受害者的文件通常会添加“.mallox”或“.mal…

Linux系统之date命令的基本使用

Linux系统之date命令的基本使用 一、date命令介绍二、检查本地系统环境2.1 检查系统版本2.2 检查yum仓库 三、date命令的使用帮助3.1 date命令的帮助信息3.2 date命令参数解释3.3 date命令常用的选项 四、date命令的日常使用4.1 直接显示时间4.2 格式化输出时间4.3 时间格式转换…

【LeetCode每日一题】——862.和至少为 K 的最短子数组

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时空频度】九【代码实现】十【提交结果】 一【题目类别】 前缀和 二【题目难度】 困难 三【题目编号】 862.和至少为 K 的最短子数组 四【题目描述】 …

【ROS2】Qt和ROS混合编程:多继承QObject和rclcpp::Node

1、说明 如果想在一个类中,即使用Qt的信号和槽(程序内部通信),同时也使用ROS2的发布、订阅消息机制(程序之间通信),如何操作? 可以尝试多重继承:QObject 和 rclcpp::Node 2、示例 1)头文件 class laoer_object_node : public QObject, public rclcpp::Node {Q_O…

我在1024谈华为

华为的发展历程与技术创新 华为自成立以来&#xff0c;一直是通信技术领域的重要参与者。让我们回顾一下华为的一些关键发展里程碑&#xff1a; 1987年&#xff0c;华为在深圳成立&#xff0c;起初专注于电话交换网络的研发和销售。 进入1990年代&#xff0c;华为转型为通信…

容器化核心快速入门

概述 物理机&#xff1a;好比是独立的大船&#xff0c;独立发动机&#xff0c;独立船舱。所有资源共用。运水果的同时就不能运鱼&#xff08; 1964年&#xff09;虚拟机&#xff1a;相当于把大船进行改造&#xff0c;把大船的资源进行独立的拆分&#xff0c;独立的部分都有单独…

适合自己的才行-这五款项目管理软件工具帮你提高管理效能

凭借多年项目管理经验&#xff0c;我试用过数十款国内外项目管理软件。我认为&#xff0c;操作简便性至关重要&#xff0c;因为软件仅是辅助管理工具&#xff0c;复杂性若影响管理本质&#xff0c;则得不偿失。 在生产管理方面&#xff0c;我专注于新产品从立项到研发的全过程…

【网络原理】HTTPS

目录 前言 为什么要使用HTTPS&#xff1f; HTTPS是如果进行加密的 1.对称加密 2.非对称加密 中间人攻击 3.证书 中间人有没有可能篡改证书&#xff1f; 中间人有没有可能整个调包证书&#xff1f; 前言 在上一篇中&#xff0c;我们讲解了什么是HTTP&#xff0c;但是在…

现代数字信号处理I--最佳线性无偏估计 BLUE 学习笔记

目录 1. 最佳线性无偏估计的由来 2. 简单线性模型下一维参数的BLUE 3. 一般线性模型下一维参数的BLUE 4. 一般线性模型下多维参数的BLUE 4.1 以一维情况说明Rao论文中的结论 4.2 矢量参数是MVUE的本质是矢量参数中的每个一维参数都是MVUE 4.3 一般线性模型多维参数BLUE的…

高性能数据分析利器DuckDB在Python中的使用

DuckDB具有极强的单机数据分析性能表现&#xff0c;功能丰富&#xff0c;具有诸多拓展插件&#xff0c;且除了默认的SQL查询方式外&#xff0c;还非常友好地支持在Python、R、Java、Node.js等语言环境下使用&#xff0c;特别是在Python中使用非常的灵活方便。 安装 pip insta…

[简易版] 自动化脚本

前言 uniapp cli项目中没办法自动化打开微信开发者工具&#xff0c;需要手动打开比较繁琐&#xff0c;故此自动化脚本就诞生啦~ 实现 const spawn require("cross-spawn"); const chalk require("picocolors"); const dayjs require("dayjs&quo…

牛客网刷题(1)(java之数据类型、数组的创建(静态/动态初始化)、static关键字与静态属性和方法、常用的servlet包、面向对象程序设计方法优点)

目录 一、Java变量的数据类型。 <1>Java中变量的数据类型。 <2>基本数据类型。 <3>引用数据类型。 二、Java中一维数组的初始化。&#xff08;静态、动态初始化&#xff09; <1>数组。 <2>动态初始化。 <3>静态初始化。 三、看清代码后&am…