element-ui 的FormItem组件是如何进行绑定值校验的【源码解读】

1.前言

使用element-ui框架有两年了,涉及到el-form组件的校验,只是根据官网给的示例使用。el-form绑定model,el-form-item绑定prop属性,el-form-item内的表单绑定v-model。只要v-model绑定的属性与prop属性一致再加上各种校验规则,即可实现某个表单的校验。

所以个人就下意识的以为一定要用v-model绑定某个值才能实现校验,在封装自定义组件时,就会下意识的用组件实现v-model绑定值的功能。但是有次在使用同事封装的组件时,他并不是使用的v-model绑定的,而是用:xxx.sync实现的某个属性值父子组件同步修改。但是也是能实现el-form表单的校验。这让我大为震撼。同事虽然解释半天,但是我还是没理解。因此决定自己看源码是什么原因。

虽然源码没有完全看懂,但是为什么不是用v-model绑定的属性也能触发校验的原理可以说基本弄懂了。

2.blur与change事件的绑定

先看el-form组件的构成:
在这里插入图片描述
el-form组件存在于node_modules/element-ui/packages/form路径下,index.js是vue的注册文件,form.vueform-item.vuelabel-wrap.vue分别是el-form组件、el-form-item组件以及表单的label。还有其它需要用到的方法就先不列出来了。这篇文章只说是根据什么校验表单项的,所以只需要看form-item组件的内容即可。

先看下面一段代码:
在这里插入图片描述

  1. 在组件挂载的时候,会添加两个监听事件(changeblur)。
  2. 这两个监听事件都会触发当前el-form-item组件的校验功能。

这个$on()是用来触发自定义方法的。
这个$on的触发是写在了element-ui的各种输入表单中,即只有element-ui的输入表单才能触发changeblur的回调,直接使用原生的<input />框绑定一个v-model是无法触发的。因为在element-ui的各种输入表单(如input,checkbox,radio等)才写了this.dispatch()用来触发el-form-itemblurchange
在这里插入图片描述

3.blur或change时进行的校验

blur与change事件的绑定大致了解了,接下来看blur或change时是怎么触发校验的。

在第一张图上可以看到在blur或change时会执行一个validate('blur'/'change')方法。接下来看看这个validate方法:
在这里插入图片描述

  • 由于el-formel-form-item都可以加上校验规则rules字段,因此方框1内是用来过滤校验规则的。
  • descriptor用来删除校验规则中的trigger属性(可能由于第三方库async-validator不需要这个字段)
  • 第三个红色大方框内是第三方库[async-validator](https://gitcode.net/mirrors/yiminghe/async-validator?utm_source=csdn_github_accelerator)根据校验规则对象descriptor对对象model进行校验的过程,当校验不通过时根据validateStatevalidateMessage这两个字段展示el-form-item的提示警告信息。

不过关于这篇文章的标题的解答,主要还是在234行那个this.fieldValue上,很明显,这个fieldValue就是当前表单项(el-form-item)绑定的值。在computer中有个计算属性fieldValue
在这里插入图片描述
它用到了element的utils中的一个getPropByPath方法,这个方法具体功能是什么确实是没太看懂。不过它最终输出的是一个包含对象、键、值的对象,传入一个对象与一个属性名即可得到对应的值。然后做了某种过滤操作。这里简单理解为从对象中取值即可。

这个computer里面的getPropByPath()方法可以理解为根据当前el-form-itemprop字段从当前el-form标签model属性绑定的对象中取值。看到这里,el-form触发校验的原理大致应该就能理解了。

3.小结

简单概括就是:

  • 校验的是 el-form-itemprop字段绑定的字段与el-formmodel对象中对应的字段的值,如下图的age字段:
    在这里插入图片描述
    当执行blurchange的校验时,校验的是form.age,即使你下方的el-inputv-model绑定的是form.name。它也校验的是form.age字段。因此需要propform中你需要绑定的那个那个字段一致,这也就解释了为什么我同事不用v-model绑定值也能触发校验了。

这其实很简单的东西我一直没有去了解,太菜了。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值