The jQuery Validation Plugin provides drop-in validation for your existing forms, while making all kinds of customizations to fit your application really easy.
来自jquery-validation项目。大概就是提供嵌入式的方式去校验表单,灵活、便捷。
(资料图片)
<script src="jquery.js"></script><script src="jquery.validate.js"></script><script> $("form").validate();</script>
看下使用说明,确实十分方便。但是核心的问题是jq的逻辑基于页面而非js对象。在vdom的洪流中,这种校验方式注定需要被进一步剥离出来。
jquery-validation核心逻辑在#L748
check: function( element ) {...// 1 获取rules对象 {normalizer: function, f1: p1, f2: p2 ...}var rules = $( element ).rules();...// 2 获取表单获取函数if ( typeof rules.normalizer === "function" ) {normalizer = rules.normalizer; // 2.1 自定义表单获取函数} else if (typeof this.settings.normalizer === "function" ) {normalizer = this.settings.normalizer; // 2.2 通用表单获取函数}...// 3 获取表单valueval = normalizer.call( element, val );delete rules.normalizer...// 4 遍历rules对象 {f1: p1, f2: p2 ...}for ( method in rules ) {rule = { method: method, parameters: rules[ method ] };result = $.validator.methods[ method ].call( this, val, element, rule.parameters );}}
拆解后就很明显了,共分成4步。
其中第2步和第3步不是非必须的。
第4步中rules和rule近名反意可以换成两个词,这里的校验即提供了列表校验,也提供了自定义校验,这就存在自定义校验是可以包括列表校验的这层关系,列表校验增加了复杂性但是带来的收益不大甚至可以被自定义校验取代。
当然这里也可以学习到一些对象处理技巧,如delete的操作。
数据对象校验近些年虚拟DOM火起来了无论是diff算法,还是渲染跨平台的能力都预示着未来可能是vDOM的世界。
基于表单数据的校验方式就要被改造成基于表单背后的数据对象的校验方式。结合上面的分析来实现一个轻量灵活的数据对象校验器。
首要考量就是业务中的空如何定义,以js为例子。
""
是空么?0
是空么?false
是空么?undefined
是空么?null
是空么?[]
是空么?{}
是空么?我这里的结论是""
、undefined
、null
属于空,其他属于空值。
空值合并运算符,它是ES2020的一个新特性,它的作用是当一个表达式是undefined
、null
时为变量设置一个默认值。空值合并运算符在左侧的值是 null 或 undefined 时会返回问号右边的表达式。
很方便可以使用(data ?? "") === ""
这种方式来判空,而不会受到空值影响,非常巧妙。
function required(data, value) {return (data ?? "") === "" ? ((false ^ value) === 0) : true},
规则校验要比表单校验更加简单,核心代码很少,也不涉及任何依赖。
function validate(data, rules) {for (const key in data)if (!validdy.validators[Object.keys(rules[key])[0]](data[key], Object.values(rules[key])[0]))return { ok: false, msg }return { ok: true, msg: "" }},
参数解释如下。
// data 数据对象const data = {name: "",plans: [],}// rules 校验规则const rules = {name: {required: true,msg: "请填写姓名",},plans: {lenlimit: {min: 1, max: 10},msg: "最少包含一个基础套餐最多包含十个套餐",},}// validators["contains"] 定义校验函数 true为通过validators["lenlimit"] = (data, value) => validators["lenmin"](data, value.min) && validators["lenmax"](data, value.max)// validated 校验结果const validated = validate(data, rules)if (!validated.ok) { // 失败逻辑return}// 通过逻辑
数据对象校验源码已经开源到validdy,js实现,其他语言有兴趣自行了解下。
标签: