如何维护前端校验的正则
我们应该给前端的规则设置一种规范,这样方便前端做统一的处理
我认为,可以用一切皆用正则校验的思想,包含长度、可以输入的字符、禁用输入的情况。配置出正则列表,提供统一方法根据正则列表生成validator。正则列表提供一一对应的tip提示。如此可以统一每一条校验规则和对应的校验提示
也有可能存在用正则无法校验的情况,也可以通过一个方法配置,返回true or false,来看是否满足规则,并切这个规则也和一个提示对应
产品给出正则也要有一定规范
例如产品可以按照如下方式依次给出每条校验规则:长度校验、可以输入字符校验、禁用的输入情况的校验、其他非校验提示(用于可能产品希望有一个额外的非校验的tip提示)
每一个校验规则和校验提示,都要产品维护成一个文档,产品可以用其中基础的校验拼接成一个表单输入项的校验,如此也可以保证整个平台的文案提示的统一性,也方便开发人员后续维护代码
统一处理代码
如果有了上面的规范,那么我们可以抽出一个rule对象,这个对象通过配置一些正则和提示列表,我们就可以生成对应的校验的validator对象。下面给出简单样例代码,其他想要的功能都可以继续在方法中添加做同意维护处理,只要是按照对应订好了的规范的表单校验
export class MultipleRule extends Rule {
regList: (RegExp | ((value: string) => boolean))[];
regKeyList?: string[];
tipList: string[];
additionTipList?: string[];
min?: number;
max?: number;
constructor(c: {
regList?: RegExp[];
tipList?: string[];
min?: number;
max?: number;
regKeyList?: string[];
additionTipList?: string[];
}) {
super();
this.regList = c.regList || [];
this.tipList = c.tipList || [];
this.additionTipList = c.additionTipList || [];
this.min = c.min;
this.max = c.max;
this.regKeyList = c.regKeyList;
this.smartFill();
}
smartFill() {
if (this.regKeyList && this.regKeyList.length > 0) {
this.tipList = [];
this.regList = [];
if (this.min !== undefined && this.max !== undefined) {
this.regList.push(getAllCharLengthReg(this.min, this.max));
this.tipList.push(getLengthTip(this.min, this.max));
}
this.regKeyList.forEach(key => {
console.log(key, Reg[key], "ggg", typeof key);
this.regList.push(Reg[key].reg);
this.tipList.push(Reg[key].msg);
});
console.log(this.regList, this.tipList, "ggg");
}
}
getTipHtml(type: TipHtmlType = TipHtmlType.WRAP, value: string = ""): string {
return this.getTipHtmlFunctionObj[type](value);
}
getTipInvalid(): string {
return this.tipList.join(",");
}
private getTipHtmlFunctionObj = {
[TipHtmlType.WRAP]: (): string => {
let tempAdditionTipList = this.additionTipList || [];
return [...this.tipList, ...tempAdditionTipList].join("<br/>");
},
[TipHtmlType.PRIMARY]: (): string => {
let tempAdditionTipList = this.additionTipList || [];
return [...this.tipList, ...tempAdditionTipList]
.map((tip, i) => {
if (i < this.tipList.length - 1) {
return `${i + 1}、${tip}` + ";";
} else {
return `${i + 1}、${tip}` + "。";
}
})
.join("<br/>");
},
};
createValidator(type: TipInvalidType = TipInvalidType.FIRST_ERROR, c: RequiredConfig = defaultRequiredConfig) {
return (rule: any, value: any, callback: any) => {
if (!value) {
if (c.required) {
callback(new Error(c.requiredMsg));
} else {
callback();
}
}
for (let i = 0; i < this.regList.length; i++) {
let isValid: boolean;
const r = this.regList[i];
if (typeof r === "function") {
isValid = r(value);
} else {
isValid = r.test(value);
}
if (!isValid) {
if (type === TipInvalidType.FIRST_ERROR) {
callback(new Error(this.tipList[i]));
} else {
callback(new Error(this.getTipInvalid()));
}
}
}
callback();
};
}
}