Vue中如何复用@focus、@blur方法及多正则表单校验规则
Vue中focus/blur校验方法复用解决方案
针对第一个问题:根据fieldName判断当前触发字段的修复
原有代码存在两个核心问题:
- blur方法中邮箱校验逻辑执行完成后直接return,导致后续姓名校验逻辑永远无法触发
- focus和blur方法都硬编码了所有字段的错误状态操作,完全没有用到传入的
fieldName参数
修复思路:利用JS对象的动态属性名特性,通过传入的字段名拼接出对应错误状态、错误提示、绑定值的属性名,仅操作当前触发事件的字段对应属性,不影响其他字段的状态。
针对第二个问题:多正则校验规则的复用方案
将所有字段的校验规则、错误提示抽成统一的配置映射表,无需为每个字段单独编写校验函数,新增校验字段仅需在映射表中新增对应配置即可,完全复用focus、blur逻辑。
修改后完整代码
JS逻辑
const app = new Vue({ el: "#app", data: { // 补充v-model绑定的字段变量 carrierEmail: '', carrierName: '', carrierEmailError: false, carrierNameError: false, carrierEmailErrMsg: '', carrierNameErrMsg: '', }, methods: { // 校验规则配置中心,新增校验字段直接在此处加配置即可 getValidatorMap() { return { carrierEmail: { rule: /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z]+$/, errMsg: '邮箱格式不正确' }, carrierName: { rule: /^[A-Za-z0-9]{1,10}$/, errMsg: '姓名只能为1-10位字母或数字组合' } } }, focus(fieldName) { // 仅清空当前触发字段的错误状态 this[`${fieldName}Error`] = false this[`${fieldName}ErrMsg`] = '' }, blur(fieldName) { const validator = this.getValidatorMap()[fieldName] // 无对应校验规则直接返回 if (!validator) return // 校验当前字段值 const isPass = validator.rule.test(this[fieldName]) if (isPass) { this[`${fieldName}Error`] = false this[`${fieldName}ErrMsg`] = '' } else { this[`${fieldName}Error`] = true this[`${fieldName}ErrMsg`] = validator.errMsg } }, // 补充原代码缺失的清空字段方法 clearField(fieldName) { this[fieldName] = '' this[`${fieldName}Error`] = false this[`${fieldName}ErrMsg`] = '' } } })
HTML模板
<html> <head> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> </head> <body> <div id="app"> <div class="form-control invoice-form" :class="{ 'is-invalid': carrierEmailError }"> <input v-model="carrierEmail" @blur="blur('carrierEmail')" @focus="focus('carrierEmail')" type="text" placeholder="E-MAIL"> </div> <div class="invalid-feedback" v-show="carrierEmailError"> {{ carrierEmailErrMsg }} </div> <div class="form-control invoice-form" :class="{ 'is-invalid': carrierNameError }"> <input v-model="carrierName" @blur="blur('carrierName')" @focus="focus('carrierName')" type="text" placeholder="name"> <div class="ic-clear" @click="clearField('carrierName')"></div> </div> <div class="invalid-feedback" v-show="carrierNameError">{{ carrierNameErrMsg }}</div> </div> </body> </html>
内容的提问来源于stack exchange,提问作者Chieh YU WU
相关产品推荐
相关产品推荐

