前言
之前写过表单校验的规则,翻回去看到的时候感觉逻辑不太清晰。希望能写一个扩展性好一些的校验,使用策略模式尝试修改一下。
策略模式
定义一系列的算法,然后把它们一个个的封装起来,这些封装起来的算法可以相互替换。
点击
当点击提交时校验各必填项是否填写,并且(id,手机号等)需要添加各自额外的校验规则。首先来实现每项不为空的校验,创建策略对象
const strategy = { hasValue(value, {errMsg}) { if (!value) { return errMsg } }}复制代码
export const validatorValue = function validator(value, fnc, err) { return strategies[fnc](value, err)}复制代码
通过核心思想是 将做什么和谁去做相分离管理函数
负责指定策略对象下的具体的函数
去执行。回到表单验证,每项需要验证的规则都不一样我们可以在策略对象下添加rule属性
来规定每项校验的规则。
// 引入第三方插件负责校验返回Boolean值import {isMobilePhone} from 'validator/index.js'import {isValidID} from '../../../utils/identification'// 校验策略类const strategy = { handle: { hasValue(value, {errMsg}) { if (!value) { return errMsg } }, minLength(value, {errMsg, param}) { if (value.length < param) { return errMsg } }, isMobile(value, {errMsg}) { if (!isMobilePhone(value, ['zh-CN'])) { return errMsg } }, isIdCard(value, {errMsg}) { console.log(value, 'value', isValidID(value, 'any')) if (!isValidID(value)) { return errMsg } } }, rule: { agency: [ { name: 'minLength', errMsg: '机构名称长度不能小于6位!', param: 6 } ], code: [], legalName: [], id: [ { name: 'isIdCard', errMsg: '请输入正确的身份证号' } ], contactName: [], phone: [ { name: 'isMobile', errMsg: '请输入正确的手机号' } ], adrress: [] }}// 给每项都设置为必填项function require(rule, errMsg) { for (let type in rule) { rule[type].unshift({ name: 'hasValue', errMsg: errMsg }) }}/** * 对表单具体值进行校验,如有错误,返回错误信息 * @param {errMsg} 必填项的错误信息 * @param {validator} 策略类下的方法名 * @return {value} 校验的值 */export const validatorValue = function (errMsg, validator, value) { // 给每项都添加必填规则 require(strategy.rule, errMsg) const errList = strategy.rule[validator] // 校验规则 for (let err of errList) { const result = strategy.handle[err.name](value, err) // 如果有值则返回第一个错误值 if (result) { return result } }}复制代码
// index.vueimport { validatorValue } from './strategy.js'export default { methods:{ checkInvalid() { const childrenList = this.$refs.group.$children for (let item of childrenList) { this.toastText = validatorValue( item.title.slice(1, -1) + '不能为空', item.name, item.currentValue ) if (this.toastText) { break } } }}复制代码
如果我们需要添加新的校验项,只需给校验项添加如 name="id" 然后在strategy.rule属性添加校验规则数组即可。
strategy{ rule:{ id:[ { name: 'minLength', errMsg: 'id长度不能小于18位!', param: 18 } ] }}复制代码
小结
策略模式需要将环境类和 具体策略类分离开,提高了可读性和维护性。