需求之前的表单代码看了下写的比较冗长于是去万能的Github找点轮子发现了这个GitHub - aweiu/element-ui-verify: 如果你受够了饿了么ElementUI原生的校验方式那就来试试它吧一款更懂你的校验插件但是用起来发现不支持最新的vue因为里面基于mixin混入。改了一会没耐性了这么简单个功能自己卷个轮子算了索性自己改但是要有以下几点支持1支持label提示例如必输的信息如果前面label为用户的话输入框提示为“用户昵称不为空”如果是最小长度检测的话需要提示“用户昵称最少4字符”。而用户昵称的校验器我只需要设置“用户昵称”这个变量提示信息自动拼接2支持验证器组合例如同时非空且为数值格式。3支持自定义提示信息不要自己构造方法最好都参数化解决思路既然都Typescript了我们就采用对象的方式来解决问题。问题1的方式只需要在构造器里添加label信息即可。问题2的方式写过后端的都知道有个很舒服的方式叫做 链式调用OK把多行代码压缩为一行个的方式就它了。问题3给个可选参数就好这个是es5的好工具结合typescript的默认值操作很方便的解决问题4有些代码直接照搬了github其它未测试的部分理论上应该没问题有BUG再回来改效果以修改密码的业务为例这样个界面改造前原来代码/** 修改密码窗体模块 */ template cc-window refwindowDom v-bind$attrs title修改当前用户密码 width400px :append-to-bodytrue submitonSubmit el-form refeditFormDom :modelform auto-completeoff :label-width100 classh-rmargin40 :rulesformRules el-form-item propuserPsw label输入密码 el-input typepassword v-modelform.userPsw maxlength20 show-password / /el-form-item el-form-item classx-fillitem propreUserPsw label确认密码 el-input typepassword v-modelform.reUserPsw maxlength20 show-password / /el-form-item /el-form /cc-window /template校验部分const formRules reactive{ userPsw: any[] reUserPsw: any[] }({ userPsw: [ { required: true, message: 请输入密码, trigger: [change, blur] }, { pattern: /^(?![0-9]$)(?![a-zA-Z]$)[0-9A-Za-z]\S{5,20}$/, message: 需同时含有字母和数字长度在6-20之间, trigger: [change, blur] } ], reUserPsw: [ { required: true, message: 请重新输入密码, trigger: [change, blur] }, { validator: (rule: any, value: any, callback: object) { return value form.userPsw }, message: 两次输入的密码不相等, trigger: [change, blur] } ] })改造后/** 修改密码窗体模块 */ template cc-window refwindowDom v-bind$attrs title修改当前用户密码 width400px :append-to-bodytrue submitonSubmit el-form refeditFormDom :modelform auto-completeoff :label-width100 classh-rmargin40 el-form-item propuserPsw label输入密码 :rules utils .validate(密码) .required() .pattern(/^(?![0-9]$)(?![a-zA-Z]$)[0-9A-Za-z]\S{5,20}$/, 需同时含有字母和数字长度在6-20之间) el-input typepassword v-modelform.userPsw maxlength20 show-password / /el-form-item el-form-item classx-fillitem propreUserPsw label确认密码 :rulesutils.validate(密码).compare(form.userPsw) el-input typepassword v-modelform.reUserPsw maxlength20 show-password / /el-form-item /el-form /cc-window /template可见简短了很多方便使用还避免了出错代码实现代码实现也不复杂写一个模块即可解决/** * 链式校验模块支持常用校验方式 * * 使用列 * import {validate} from /commons/utils/Validator * * //建立一个非空4字符以上的昵称校验未输入提示“请输入昵称”过短提示“昵称长度最小为 4 字符” * validate(昵称).required().minLength(4) * * 注意除了非空校验外其它校验都是为空可以通过的除非显示的指定了非空校验required * * author Jim 24/09/20 */ export interface IValidator extends Arrayany { required: (error?: string) IValidator // 必须输入 gt: (value: number, error?: string) IValidator // 必须大于 gte: (value: number, error?: string) IValidator // 必须大于等于 lt: (value: number, error?: string) IValidator // 必须小于于 lte: (value: number, error?: string) IValidator // 必须小于等于 minLength: (size: number, error?: string) IValidator // 不能小于X字符 maxLength: (size: number, error?: string) IValidator // 不能超过X字符用于textArea校验 precision: (digitSize: number, error?: string) IValidator // 校验数字最大小数位(精度限制) number: () IValidator // 校验是否为数字 int: () IValidator // 校验是否为整数 phone: () IValidator // 校验是否为手机号随着号段的增加未来可能需要更新 email: () IValidator // 校验是否为电子邮件地址 verifyCode: (size: number) IValidator // 校验指定长度验证码默认6位 pattern: (regex: RegExp, error?: string) IValidator // 校验正则格式 compare: (otherVal: string, error?: string) Validator // 校验两次输入一致 } export class Validator extends Array implements IValidator { private labelText?: string undefined constructor(label?: string) { super(0) this.labelText label return this } required(error?: string): Validator { this.push({ required: true, message: error ?? (this.labelText ? 请输入${this.labelText} : 输入不能为空), trigger: [change, blur] }) return this } gt(value: number, error?: string): Validator { this.push({ validator: (rule: any, val: any, callback: (error?: Error) void) { return !val || val value }, message: error ?? ${this.labelText ?? 输入数值}应大于 ${value}, trigger: [change, blur] }) return this } gte(value: number, error?: string): Validator { this.push({ type: number, min: value, transform: (v: string) Number(v), message: error ?? ${this.labelText ?? 输入数值}不能小于 ${value}, trigger: [change, blur] }) return this } lt(value: number, error?: string): Validator { this.push({ validator: (rule: any, val: any, callback: (error?: Error) void) { return !val || val value }, message: error ?? ${this.labelText ?? 输入数值}应小于 ${value}, trigger: [change, blur] }) return this } lte(value: number, error?: string): Validator { this.push({ type: number, max: value, transform: (v: string) Number(v), message: error ?? ${this.labelText ?? 输入数值}不能大于 ${value}, trigger: [change, blur] }) return this } minLength(size: number, error?: string): Validator { this.push({ validator: (rule: any, val: any, callback: (error?: Error) void) { return (val?.length || 0) size }, message: error ?? ${this.labelText ?? 内容}长度最小为 ${size} 字符, trigger: [change, blur] }) return this } maxLength(size: number, error?: string): Validator { this.push({ validator: (rule: any, val: any, callback: (error?: Error) void) { return (val?.length || 0) size }, message: error ?? ${this.labelText ?? 内容}长度最多为 ${size} 字符, trigger: [change, blur] }) return this } precision(digitSize: number, error?: string): Validator { this.push({ validator: (rule: any, val: any, callback: (error?: Error) void) { const decimal val.toString().split(.)[1] return !!decimal decimal.length digitSize }, message: error ?? ${this.labelText ?? }小数部分不能超过 ${digitSize} 位, trigger: [change, blur] }) return this } number(): Validator { return this.pattern(/^([-])?\d(\.\d)?$/, ${this.labelText ?? }请输入数字) } int(): Validator { this.push({ type: integer, transform: (v: string) Number(v), message: 请输入整数, trigger: [change, blur] }) return this } phone(): Validator { return this.pattern(/^1\d{10}$/, 请输入正确手机号码) } email(): Validator { this.push({ type: email, message: 邮箱格式不正确, trigger: [change, blur] }) return this } verifyCode(size: number 6): Validator { const pattern new RegExp(^\\d{${size}}$) return this.pattern(pattern, 输入${size}位验证码) } compare(otherVal: string, error?: string): Validator { this.push({ validator: (rule: any, val: any, callback: (error?: Error) void) { return !val || val otherVal }, message: error ?? ${this.labelText ?? }两次输入不一致, trigger: [change, blur] }) return this } pattern(regex: RegExp, error?: string) { this.push({ validator: (rule: any, val: any, callback: (error?: Error) void) { return !val || regex.test(val) }, message: error ?? 请输入正确格式, trigger: [change, blur] }) return this } } export const validate: (label?: string) IValidator (label) { return new Validator(label) }不到200行搞掂小遗憾与element-ui-verify相比唯一有点小遗憾的这种方式还是基于配置无法自动获取到label的信息了不然定义完label后还得重复写一次精简的不够极致。而且也无法响应校验的配置变化算一点小遗憾了以后有空再继续改造--------------------- [ 2024/06/05 新增 ] ---------------------今天改造个vue2项目也需要校验偷个懒让GPT翻译成了javascript能用/* eslint-disable no-unused-vars */ /** * 链式校验模块支持常用校验方式 * * 使用列 * import Validator from /commons/utils/validator * * //建立一个非空4字符以上的昵称校验未输入提示“请输入昵称”过短提示“昵称长度最小为 4 字符” * new Validator(昵称).required().minLength(4) * * 注意除了非空校验外其它校验都是为空可以通过的除非显示的指定了非空校验required * * author Jim 24/06/05 */ export default class Validator extends Array { constructor(label) { super(); this.labelText label; return this; } required(error) { this.push({ required: true, message: error ?? (this.labelText ? 请输入${this.labelText} : 输入不能为空), trigger: [change, blur] }); return this; } gt(value, error) { this.push({ validator: (rule, val, callback) { return !val || val value; }, message: error ?? ${this.labelText ?? 输入数值}应大于 ${value}, trigger: [change, blur] }); return this; } gte(value, error) { this.push({ type: number, min: value, transform: (v) Number(v), message: error ?? ${this.labelText ?? 输入数值}不能小于 ${value}, trigger: [change, blur] }); return this; } lt(value, error) { this.push({ validator: (rule, val, callback) { return !val || val value; }, message: error ?? ${this.labelText ?? 输入数值}应小于 ${value}, trigger: [change, blur] }); return this; } lte(value, error) { this.push({ type: number, max: value, transform: (v) Number(v), message: error ?? ${this.labelText ?? 输入数值}不能大于 ${value}, trigger: [change, blur] }); return this; } minLength(size, error) { this.push({ validator: (rule, val, callback) { return (val?.length || 0) size; }, message: error ?? ${this.labelText ?? 内容}长度最小为 ${size} 字符, trigger: [change, blur] }); return this; } maxLength(size, error) { this.push({ validator: (rule, val, callback) { return (val?.length || 0) size; }, message: error ?? ${this.labelText ?? 内容}长度最多为 ${size} 字符, trigger: [change, blur] }); return this; } precision(digitSize, error) { this.push({ validator: (rule, val, callback) { const decimal val.toString().split(.)[1]; return !!decimal decimal.length digitSize; }, message: error ?? ${this.labelText ?? }小数部分不能超过 ${digitSize} 位, trigger: [change, blur] }); return this; } number() { return this.pattern(/^([-])?\d(\.\d)?$/, ${this.labelText ?? }请输入数字); } int() { this.push({ type: integer, transform: (v) Number(v), message: 请输入整数, trigger: [change, blur] }); return this; } phone() { return this.pattern(/^1\d{10}$/, 请输入正确手机号码); } email() { this.push({ type: email, message: 邮箱格式不正确, trigger: [change, blur] }); return this; } verifyCode() { return this.pattern(/^([-])?\d(\.\d)?$/, 请输入验证码); } compare(otherVal, error) { this.push({ validator: (rule, val, callback) { return !val || val otherVal; }, message: error ?? ${this.labelText ?? }两次输入不一致, trigger: [change, blur] }); return this; } pattern(regex, error) { this.push({ validator: (rule, val, callback) { return !val || regex.test(val); }, message: error ?? 请输入正确格式, trigger: [change, blur] }); return this; } } const validate (label) { return new Validator(label); } export { validate };关键代码el-form-item label批次名称 propbatchName :rulesnew Validator(批次名称).required() el-input v-modelform.batchName placeholder方便管理的名称领用人/领用日期等 stylewidth: 300px; maxlength32 / /el-form-item .... import Validator from /utils/validator export default { data() { return { Validator } }, ....------------------------ [24/09/20新增] ---------------------------修复了验证码判断的逻辑增加了多语言翻译。不使用CcFrame框架的可以不用继续看了。这里记录下验证还没翻译完进行中。最新的代码Validator.ts:/** * 链式校验模块支持常用校验方式 * * 使用列 * import {validate} from /commons/utils/Validator * * //建立一个非空4字符以上的昵称校验未输入提示“请输入昵称”过短提示“昵称长度最小为 4 字符” * validate(昵称).required().minLength(4) * * 注意除了非空校验外其它校验都是为空可以通过的除非显示的指定了非空校验required * * [24/08/17]支持直接构建的对象进行校验输出错误信息. * [24/09/19]整合多语言. * * author Jim 24/09/19 */ export interface IValidator extends Arrayany { required: (error?: string) IValidator // 必须输入 gt: (value: number, error?: string) IValidator // 必须大于 gte: (value: number, error?: string) IValidator // 必须大于等于 lt: (value: number, error?: string) IValidator // 必须小于于 lte: (value: number, error?: string) IValidator // 必须小于等于 minLength: (size: number, error?: string) IValidator // 不能小于X字符 maxLength: (size: number, error?: string) IValidator // 不能超过X字符用于textArea校验 precision: (digitSize: number, error?: string) IValidator // 校验数字最大小数位(精度限制) number: () IValidator // 校验是否为数字 int: () IValidator // 校验是否为整数 phone: () IValidator // 校验是否为手机号随着号段的增加未来可能需要更新 email: () IValidator // 校验是否为电子邮件地址 verifyCode: (size: number) IValidator // 校验指定长度验证码默认6位 pattern: (regex: RegExp, error?: string) IValidator // 校验正则格式 compare: (otherVal: string, error?: string) Validator // 校验两次输入一致 validateRaw(value: any): string // 原始校验模式 } export class Validator extends Array implements IValidator { private labelText?: string undefined constructor(label?: string) { super(0) this.labelText label return this } required(error?: string): Validator { this.push({ required: true, validator: (rule: any, val: any, callback: (error?: Error) void) { // 补充验证模式 return val ! undefined val ! null val ! }, message: error ?? (this.labelText ? $t(utils.validator.required) this.labelText : $t(utils.validator.notEmpty)), trigger: [change, blur] }) return this } gt(value: number, error?: string): Validator { this.push({ validator: (rule: any, val: any, callback: (error?: Error) void) { return !(val null || val undefined) val value }, message: error ?? ${this.labelText ?? $t(utils.validator.inputNumber)}应大于 ${value}, trigger: [change, blur] }) return this } gte(value: number, error?: string): Validator { this.push({ type: number, min: value, transform: (v: string) Number(v), message: error ?? ${this.labelText ?? $t(utils.validator.inputNumber)}不能小于 ${value}, trigger: [change, blur] }) return this } lt(value: number, error?: string): Validator { this.push({ validator: (rule: any, val: any, callback: (error?: Error) void) { return !(val null || val undefined) val value }, message: error ?? ${this.labelText ?? $t(utils.validator.inputNumber)}应小于 ${value}, trigger: [change, blur] }) return this } lte(value: number, error?: string): Validator { this.push({ type: number, max: value, transform: (v: string) Number(v), message: error ?? ${this.labelText ?? $t(utils.validator.inputNumber)}不能大于 ${value}, trigger: [change, blur] }) return this } minLength(size: number, error?: string): Validator { this.push({ validator: (rule: any, val: any, callback: (error?: Error) void) { return (val?.length || 0) size }, message: error ?? (this.labelText ?? $t(utils.validator.inputContent)) $t(utils.validator.minLength, { size }), trigger: [change, blur] }) return this } maxLength(size: number, error?: string): Validator { this.push({ validator: (rule: any, val: any, callback: (error?: Error) void) { return (val?.length || 0) size }, message: error ?? ${this.labelText ?? $t(utils.validator.inputContent)}长度最多为 ${size} 字符, trigger: [change, blur] }) return this } precision(digitSize: number, error?: string): Validator { this.push({ validator: (rule: any, val: any, callback: (error?: Error) void) { const decimal val.toString().split(.)[1] return !!decimal decimal.length digitSize }, message: error ?? ${this.labelText ?? }小数部分不能超过 ${digitSize} 位, trigger: [change, blur] }) return this } number(): Validator { return this.pattern(/^([-])?\d(\.\d)?$/, ${this.labelText ?? }请输入数字) } int(): Validator { this.push({ type: integer, transform: (v: string) Number(v), message: 请输入整数, trigger: [change, blur] }) return this } phone(): Validator { return this.pattern(/^1\d{10}$/, 请输入正确手机号码) } email(): Validator { this.push({ type: email, message: 邮箱格式不正确, trigger: [change, blur] }) return this } verifyCode(size: number 6): Validator { const pattern new RegExp(^\\d{${size}}$) return this.pattern(pattern, 输入${size}位验证码) } compare(otherVal: string, error?: string): Validator { this.push({ validator: (rule: any, val: any, callback: (error?: Error) void) { return !val || val otherVal }, message: error ?? $t(utils.validator.compare, { inputs: this.labelText ?? }), trigger: [change, blur] }) return this } pattern(regex: RegExp, error?: string) { this.push({ validator: (rule: any, val: any, callback: (error?: Error) void) { return !val || regex.test(val) }, message: error ?? 请输入正确格式, trigger: [change, blur] }) return this } validateRaw(value: any): string { for (const validation of this) { const isValid validation.validator ? validation.validator(null, value, () {}) : true if (!isValid) { return validation.message } } return } } export const validate: (label?: string) IValidator (label) { return new Validator(label) }------------------------ [24/12/17新增] ---------------------------修复了ge和le判断数值为0的问题更新前一个Validator.ts