el-table通过这样封装可以实现校验-表格校验的原理

我们一般在后台系统中,很常见的操作时表格里面嵌套表单,之前我的网上找到了一些封装的用法:

<el-form :model="formData" :rules="ruleData" ref="formDom"><el-table :data="formData.tableData"><el-table-columnv-for="item in column":key="item.prop":label="item.label"><template slot-scope="scope"><el-form-item:ref="'tableData.' + scope.$index + '.' + item.prop":prop="'tableData.' + scope.$index + '.' + item.prop":rules="ruleData[item.prop]"><el-inputv-model="scope.row[item.prop]"@change="handleChange(scope, item)"></el-input></el-form-item></template></el-table-column></el-table>
</el-form>// data中的数据
formData: {tableData: [{ name: "", age: "" },{ name: "", age: "" },{ name: "", age: "" },{ name: "", age: "" },],
},
ruleData: {name: { message: "请输入名字", required: true },age: { message: "请输入年龄", required: true },
},
column: [{ label: "名字", prop: "name" },{ label: "年龄", prop: "age" },
],

在这里我不太理解prop为什么要写成"'tableData.' + scope.$index + '.' + item.prop"这个样子就实现了校验的效果。后来在一次项目中偶然去查看了一下el-form的源码,才明白其中的道理;
在这里插入图片描述
首先我们看到el-form组件的文件路径是这样的,那么其实form-item是一个单独的组件,我们通过form -> form-item嵌套的时候,其实最后实现校验的过程是一个个去校验 form-item,form组件最终的校验:

// 最主要的核心功能
validate(callback){this.fields.forEach(field => {field.validate('', (message, field) => {if (message) {valid = false;}invalidFields = objectAssign({}, invalidFields, field);if (typeof callback === 'function' && ++count === this.fields.length) {callback(valid, invalidFields);}});
});
}

其中 this.fields就是el-form-item集合:

// el-form的created中
this.$on('el.form.addField', (field) => {if (field) {this.fields.push(field);}
});// el-form-item的mounted中
this.dispatch('ElForm', 'el.form.addField', [this]);// 内部自己使用 dispatch实现组件通讯

其中最主要的就是调用el-form-itemvalidate方法:

validate(trigger, callback = noop) {this.validateDisabled = false;const rules = this.getFilteredRule(trigger);if ((!rules || rules.length === 0) && this.required === undefined) {callback();return true;}this.validateState = 'validating';const descriptor = {};if (rules && rules.length > 0) {rules.forEach(rule => {delete rule.trigger;});}descriptor[this.prop] = rules;const validator = new AsyncValidator(descriptor);const model = {};model[this.prop] = this.fieldValue;validator.validate(model, { firstFields: true }, (errors, invalidFields) => {this.validateState = !errors ? 'success' : 'error';this.validateMessage = errors ? errors[0].message : '';callback(this.validateMessage, invalidFields);this.elForm && this.elForm.$emit('validate', this.prop, !errors, this.validateMessage || null);});}

其中主要的核心功能是单个的 rules(校验规则)model(数据)
rules的获取:

// 首先通过getFilteredRule方法过滤rules
getFilteredRule(trigger) {// 获取 rulesconst rules = this.getRules();return rules.filter(rule => {if (!rule.trigger || trigger === '') return true;if (Array.isArray(rule.trigger)) {return rule.trigger.indexOf(trigger) > -1;} else {return rule.trigger === trigger;}}).map(rule => objectAssign({}, rule));
},// getFilteredRule最核心的方式就是getRules
getRules() {// 这个就是我们在 el-form中传递的ruleslet formRules = this.form.rules;// 这个就是我们自己在 el-form-item传递的rulesconst selfRules = this.rules;// 这里判断是不是必输的const requiredRule = this.required !== undefined ? { required: !!this.required } : [];// 这里通过formRules结合prop获取最新的prop(其实是一个对象,里面有key,value比较重要的值)const prop = getPropByPath(formRules, this.prop || '');formRules = formRules ? (prop.o[this.prop || ''] || prop.v) : [];// 最终将rules做一个整合return [].concat(selfRules || formRules || []).concat(requiredRule);
},

最终我们通过分析发现其实去匹配 el-form中整体的rules是通过getPropByPath这个方法的:

function getPropByPath(obj, path) {let tempObj = obj;path = path.replace(/\[(\w+)\]/g, '.$1');path = path.replace(/^\./, '');let keyArr = path.split('.');let i = 0;for (let len = keyArr.length; i < len - 1; ++i) {let key = keyArr[i];if (key in tempObj) {tempObj = tempObj[key];} else {throw new Error('please transfer a valid prop path to form item!');}}return {o: tempObj,k: keyArr[i],v: tempObj[keyArr[i]]};
}

path.split('.')这里会对prop进行切割,我们最终得到的值其实是这样的:
在这里插入图片描述
最终通过formRules = formRules ? (prop.o[this.prop || ''] || prop.v) : [];formRules这个值变成了undefined
再返回validate方法里面,看model,通过这里model[this.prop] = this.fieldValue,我们来看fieldValue

function getPropByPath(obj, path) {// 这里的值其实一个对象数组:// { tableData: [// { name: "", age: "" },// { name: "", age: "" },// { name: "", age: "" },// { name: "", age: "" },
// ] },let tempObj = obj;path = path.replace(/\[(\w+)\]/g, '.$1');path = path.replace(/^\./, '');// 那第一个来说就是 tableData.0.namelet keyArr = path.split('.');let i = 0;for (let len = keyArr.length; i < len - 1; ++i) {// 不断的去匹配 tempObj 中的值let key = keyArr[i];if (key in tempObj) {tempObj = tempObj[key];} else {throw new Error('please transfer a valid prop path to form item!');}}return {o: tempObj,k: keyArr[i],v: tempObj[keyArr[i]]};
}
// 其实就是一个计算属性
fieldValue() {// 我们给 el-form传递的model值const model = this.form.model;if (!model || !this.prop) { return; }let path = this.prop;if (path.indexOf(':') !== -1) {path = path.replace(/:/, '.');}// 还是通过这个方法获取到对应的值return getPropByPath(model, path, true).v;
},

最终fieldValue就表示了表格组件中每个小块的值,通过 propmodel去匹配对应的值,和rules结合AsyncValidator实现表单校验。这里我们也可以看出给el-form传递model,给el-form-item传递proprules的重要性。
写到这里我还有一个疑问,那就是在getRules方法中,通过getPropByPath其实最终是把formRules转换成一个undefined的,那么是不是在此次封装中给el-form传递的rules没用了,其实真正起主导作用的还是给el-form-item传递的rules,那么把el-form-item中的rules删除掉是不是就校验不了了。通过验证证实了我的猜想。

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

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

相关文章

WordPress分类目录ID怎么看?如何查找WordPress标签ID?

在WordPress网站中&#xff0c;我们需要判断某篇文章是否属于某个分类目录&#xff0c;或者是否拥有某个标签&#xff0c;那么就需要用到分类目录ID和标签ID&#xff0c;那么WordPress分类目录ID怎么看&#xff1f;如何查找WordPress标签ID&#xff1f;下面boke112百科就跟大家…

Node.js基础---加载机制

模块的加载机制 1. 优先成缓存中加载 模块在第一次加载后会被缓存&#xff0c;意味着多次调用 require() 不会导致模块代码被多次执行 注意&#xff1a;无论是什么模块都会优先从缓存内加载&#xff0c;以提高加载效率 2. 内置模块的加载机制 内置模块是 Node.js官网提供的模块…

【论文阅读】微纳米气泡技术作为CO2-EOR和CO2地质储存技术的新方向:综述

Micro and nanobubbles technologies as a new horizon for CO2-EOR and CO2 geological storage techniques: A review 微纳米气泡技术作为CO2-EOR和CO2地质储存技术的新方向&#xff1a;综述 期刊信息&#xff1a;Fuel 2023 期刊级别&#xff1a;EI检索 SCI升级版工程技术1区…

Python实现时间序列分析进行平稳性检验(ADF和KPSS)和差分去趋势(adfuller和kpss算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 时间序列分析中的平稳性检验是评估一个时间序列是否具有稳定的均值和方差。在经济学、金融学以及其他诸…

麒麟OS:操作系统国家队

这是ren_dong的第31篇原创 1、中标软件 中标软件&#xff1a;国产操作系统龙头 中标软件有限公司成立于2003 年&#xff0c;是国产自主操作系统和办公软件产品提供商&#xff0c;拥有 国防、民用两方面的相关企业与产品资质&#xff0c;是安全操作系统旗舰企业。 中标软件的主要…

飞天使-学以致用-devops知识点3-安装jenkins

文章目录 构建带maven环境的jenkins 镜像安装jenkinsjenkins yaml 文件安装插件jenkins 配置k8s创建用户凭证 构建带maven环境的jenkins 镜像 # 构建带 maven 环境的 jenkins 镜像 docker build -t 192.168.113.122:8858/library/jenkins-maven:jdk-11 .# 登录 harbor docker …

解读人工智能的理论基石

1956年的一个夏天&#xff0c;在达特茅斯学院的一个小会议室里&#xff0c;一群充满好奇和野心的年轻科学家聚集在一起&#xff0c;他们有一个共同的梦想&#xff1a;创造能够模仿人类智能的机器。这不仅仅是科幻小说的情节&#xff0c;更是人工智能历史上一个真实的起点。从那…

基于JAVA的毕业生追踪系统 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 登陆注册模块2.2 学生基本配置模块2.3 就业状况模块2.4 学历深造模块2.5 信息汇总分析模块2.6 校友论坛模块 三、系统设计3.1 用例设计3.2 实体设计 四、系统展示五、核心代码5.1 查询我的就业状况5.2 初始化就业状况5.…

防御保护:防火墙内容安全

一、IAE&#xff08;Intelligent Awareness Engine&#xff09;引擎 二、深度检测技术(DFI和DPI&#xff09; 1.DPI – 深度包检测技术 DPI主要针对完整的数据包&#xff08;数据包分片&#xff0c;分段需要重组&#xff09;&#xff0c;之后对数据包的内容进行识别。&#x…

微服务 人工智能AI 物联网智慧工地云平台源码

目录 ​编辑 智慧工地架构 智慧工地系统 智慧工地云平台功能模块 1、基础数据管理 2、考勤管理 3、安全隐患管理 4、视频监控 5、塔吊监控 6、升降机监控 7、移动端数据推送 智慧工地管理平台子系统构成 智慧工地物联网解决方案&#xff0c;对工地施工安全人员、设…

引入本地图片报错:require is not defined

文章目录 问题分析1. 原始写法2. 最初的解决方案3. 尝试使用 require 引入4. 封装方法进行解析引入图片 问题 Vue3 Vite 使用本地图片报错&#xff1a;require is not defined 分析 1. 原始写法 刚开始我是这样写的&#xff0c;数据是这样定义的&#xff0c;但是数据没出…

【Linux深入剖析】再续环境变量 | 进程地址空间

&#x1f4d9; 作者简介 &#xff1a;RO-BERRY &#x1f4d7; 学习方向&#xff1a;致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f4d2; 日后方向 : 偏向于CPP开发以及大数据方向&#xff0c;欢迎各位关注&#xff0c;谢谢各位的支持 目录 1.环境变量再续1.1 和…

FX110网:外汇交易中的隔夜利息该如何计算?

在交易过程中&#xff0c;我们经常能够听到 “隔夜利息”这个词&#xff0c;但不少新手依然不是很明白这个专业名词的意思。今天小编帮助大家理解这个概念。“隔夜利息”的含义 顾名思义&#xff0c;是根据持仓总数计算的每日可赚取或需支付的利息。每个货币都有他们自己的基准…

贝叶斯优化双向门控循环单元BO-BIGRU时序预测的matlab实现【源代码】

贝叶斯优化双向门控循环单元简介&#xff1a; 贝叶斯优化双向门控循环单元&#xff08;BO-BIGRU&#xff09;是一种结合了贝叶斯优化和双向门控循环单元&#xff08;BIGRU&#xff09;的神经网络模型。BIGRU是一种改进的循环神经网络&#xff08;RNN&#xff09;&#xff0c;它…

现代信号处理学习笔记(二)参数估计理论

参数估计理论为我们提供了一套系统性的工具和方法&#xff0c;使我们能够从样本数据中推断总体参数&#xff0c;并评估估计的准确性和可靠性。这些概念在统计学和数据分析中起着关键的作用。 目录 前言 一、估计子的性能 1、无偏估计与渐近无偏估计 2、估计子的有效性 两个…

Python入门到精通(九)——Python数据可视化

Python数据可视化 一、JSON数据格式 1、定义 2、python数据和JSON数据转换 二、pyecharts 三、折线图 四、地图 五、动态柱状图 一、JSON数据格式 1、定义 JSON是一种轻量级的数据交互格式。可以按照JSON指定的格式去组织和封装数据JSON本质上是一个带有特定格式的字符…

嘴尚绝卤味传统与创新的完美结合

在当下这个美食文化丰富多彩的时代&#xff0c;卤味作为一种深受大众喜爱的食品&#xff0c;不仅承载着传统的烹饪智慧&#xff0c;更在不断创新中展现出新的魅力。嘴尚绝卤味&#xff0c;作为卤味市场中的佼佼者&#xff0c;凭借其独特的优势&#xff0c;正逐渐成为消费者心中…

java高级——动态代理

目录 动态代理介绍明星代理案例实现案例分析动态代理应用场景 动态代理介绍 用一个明星的案例来解释动态代理的流程。 假设现在有一个明星坤坤&#xff0c;它有唱歌和跳舞的本领&#xff0c;作为明星是要用唱歌和跳舞来赚钱的。但是每次做节目&#xff0c;唱歌的时候要准备话…

阿里云2024年服务器2核4G配置评测_CPU内存带宽_优惠价格

阿里云2核4G服务器多少钱一年&#xff1f;2核4G服务器1个月费用多少&#xff1f;2核4G服务器30元3个月、85元一年&#xff0c;轻量应用服务器2核4G4M带宽165元一年&#xff0c;企业用户2核4G5M带宽199元一年。本文阿里云服务器网整理的2核4G参加活动的主机是ECS经济型e实例和u1…

Linux磁盘性能方法以及磁盘io性能分析

Linux磁盘性能方法以及磁盘io性能分析 1. fio压测1.1. 安装fio1.2. bs 4k iodepth 1&#xff1a;随机读/写测试&#xff0c;能反映硬盘的时延性能1.3. bs 128k iodepth 32&#xff1a;顺序读/写测试&#xff0c;能反映硬盘的吞吐性能 2. dd压测2.1. 测试纯写入性能2.2. 测试…