博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
校验表单如何摆脱 if else ?
阅读量:5954 次
发布时间:2019-06-19

本文共 3887 字,大约阅读时间需要 12 分钟。

背景

现在市面上很多 ui 框架都有 form 表单校验,还有些三方库。我的应用场景是不需要和 ui 绑在一起,传统的提交校验 --- 按顺序,一个个检验。

?

比如我有个接口的参数 params1, params2 需要检验,不为空。

传统方式当然也是最快的 if else

if(!paramsN) {     alter(msgN)     return false }复制代码

策略模式

自从看了策略模式相关的文章受到了一些启发,同时搬下大佬写的自定义校验器,通过 proxy 实现的。

下面瞻仰一下同时看下如何封装

export const validatorCreater = (target, validator) => new Proxy(target, { // 保存校验器 _validator: validator, set (target, key, value, receiver) {   // 如果赋值的属性存在校验器,则进行校验   if (this._validator[key]) {     // 遍历其多个子校验器     for (let validatorStrategy of this._validator[key]) {       let {errorMsg = '', params = []} = validatorStrategy       if (!validatorStrategy.validator.call(null, value, ...params)) {         throw new Error(errorMsg)       }     }   }   // 赋值语句放最后,如果失败不赋值,如果不存在校验器则赋值   return Reflect.set(target, key, value, receiver) }})复制代码

如何使用

_checkValue = ({ parentId, baseInfo }) => {   // 这里参考策略模式   const isNotEmpty = val => val && (val + '').length > 0   const objEmpty = val => !_.isEmpty(val)   let validators = {     baseInfo: [{       validator: objEmpty,       errorMsg: 'xxxx'     }],     parentId: [{       validator: isNotEmpty,       errorMsg: 'xxxx'     }]   }   const checkObj = validatorCreater({}, validators)   try {     checkObj.parentId = parentId     checkObj.baseInfo = baseInfo   } catch (e) {     console.warn(e)     message.error(e.message)     return false   }   return true }复制代码

怎么样,看完是不是受益颇多。用了一段时间思考可不可以通过 es5 的方式来实现一个简版的呢

通过深思熟虑,还是想出了一个雏形方案如下

精简版

export const checkParams = (rules = []) => callback => { let checkStatus = true try {   for (let i = 0; i < rules.length; i++) {     const { fn, value, errorMsg } = rules[i]     if (!fn(value)) {       checkStatus = false       callback && callback(errorMsg)       break     }   } } catch (error) {   console.error(error)   console.warn(`     所属值类型------     fn: 校验函数     value:所需校验值类型     errorMsg: 错误信息   `) } return checkStatus}复制代码

外部调用

_checkParams = ({ inquiryPrice, inquiryUnit, sellStockNum }) => {   const isNotEmpty = val => val && (val + '').length > 0   const rules = [     { fn: isNotEmpty, value: inquiryPrice, errorMsg: '请填写1' },     { fn: isNotEmpty, value: inquiryUnit, errorMsg: '请选择2' },     { fn: isNotEmpty, value: sellStockNum, errorMsg: '请填3' }   ]   return checkParams(rules)(message.error) }复制代码

改进

判断为空和正则是最常用的功能,优化一下如下

const _ = require('lodash')export default (rules = []) => callback => { let checkStatus = true try {   for (let i = 0; i < rules.length; i++) {     const { fn, value, errorMsg = '该参数不合法', required, pattern } = rules[i]     // 只校验为空     if (required && !isEmpty(value)) {       checkStatus = false       callback && callback(errorMsg)       break     }     // 都需要校验正则了肯定先判空     if (pattern && isEmpty(value) && !patternCheck(pattern, value)) {       checkStatus = false       callback && callback(errorMsg)       break     }     // 自定义校验函数     if (fn && isEmpty(value) && !fn(value)) {       checkStatus = false       callback && callback(errorMsg)       break     }   } } catch (error) {   console.error(error)   console.warn(`     所属值类型------     fn: 自定义校验函数     value:所需校验值     errorMsg: 错误信息,     required: 是否必填,     pattern: 正则   `) } return checkStatus}const isEmpty = (value) => { const types = ['string', 'number'] const isExit = types.includes(typeof value) if (isExit) {   return (value + '').length > 0 } else {   if (!value) {     // 判断 null, undefined     return false   } else {     // 判断空数组、空对象     return !_.isEmpty(value)   } }}const patternCheck = (reg, value) => { if ((typeof value) === 'string') {   return reg.test(value) } else {   console.warn('正则只对string有效')   return false }}复制代码

使用

const rules = [   { value: 1, required: true},   { value: -1, fn: (val) => val > 0, pattern: /^\d{1,}$/ },   { value: -1, fn: (val) => val > 0 }   ]checkParams(rules)(console)复制代码

说白了不管什么奇思妙想都是基于策略模式实现的,包括很多库也是。所以大家想深入理解推荐大家去看策略模式

转载于:https://juejin.im/post/5c8b686fe51d45453b71f585

你可能感兴趣的文章
js中的 substring和substr方法
查看>>
wpf 界面加载 Command
查看>>
今 天看到我十年前的一篇技术文章,想到不知不觉学编程十多年了,,
查看>>
DOM(十四):代理检测和事件处理(跨浏览器)
查看>>
SqlServer存储过程调用接口
查看>>
ZOJ 3817Chinese Knot(The 2014 ACM-ICPC Asia Mudanjiang Regional First Round)
查看>>
一到十二月单词
查看>>
【算法】2 由股票收益问题再看分治算法和递归式
查看>>
Golang 笔记 2 函数、结构体、接口、指针
查看>>
Swift4 - 动态计算UITableView中tableHeaderView的高度 - 获取子控件高度和宽度
查看>>
java学习中,instanceof 关键字 和 final 关键字、值的传递(java 学习中的小记录)...
查看>>
数据结构 --- 线性表学习(php模拟)
查看>>
URAL 1081 Binary Lexicographic Sequence
查看>>
Codeforces 797B - Odd sum
查看>>
文章页调用栏目链接和栏目名称的方法
查看>>
Oracle数据库日期格式转换操作
查看>>
Play framework 2.0 -应用程序全局设置(转)
查看>>
如何将div高度填满剩余高度
查看>>
连通图
查看>>
Source insight 添加注释插件
查看>>