基于vue elementu-ui表单验证框架的js工具类之密码、确认密码验证

本文介绍了如何基于Vue和Element-UI构建表单验证工具类,特别是针对密码和确认密码的验证规则。通过优化代码,将验证规则转化为独立的JS工具类,以减少耦合并提高安全性。同时,文章讨论了存储明文数据的安全隐患,并建议将与项目相关性强的验证策略放在项目内的validation文件夹中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Vue和Element-UI这两大框架在前端开发中应用已经非常nice了。但是在开发中还是有很多不足之处。以大量的使用基础,来不断的改进吧。

常规Element的表单验证

偷个懒,这里首先去官网看看表单验证的基本用法
https://element.eleme.cn/#/zh-CN/component/form

关键代码

<el-form :model="ruleForm" status-icon :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
  <el-form-item label="密码" prop="pass">
    <el-input type="password" v-model="ruleForm.pass" autocomplete="off"></el-input>
  </el-form-item>
  <el-form-item label="确认密码" prop="checkPass">
    <el-input type="password" v-model="ruleForm.checkPass" autocomplete="off"></el-input>
  </el-form-item>
  <el-form-item label="年龄" prop="age">
    <el-input v-model.number="ruleForm.age"></el-input>
  </el-form-item>
  <el-form-item>
    <el-button type="primary" @click="submitForm('ruleForm')">提交</el-button>
    <el-button @click="resetForm('ruleForm')">重置</el-button>
  </el-form-item>
</el-form>
<script>
  export default {
    data() {
      var checkAge = (rule, value, callback) => {
        if (!value) {
          return callback(new Error('年龄不能为空'));
        }
        setTimeout(() => {
          if (!Number.isInteger(value)) {
            callback(new Error('请输入数字值'));
          } else {
            if (value < 18) {
              callback(new Error('必须年满18岁'));
            } else {
              callback();
            }
          }
        }, 1000);
      };
      var validatePass = (rule, value, callback) => {
        if (value === '') {
          callback(new Error('请输入密码'));
        } else {
          if (this.ruleForm.checkPass !== '') {
            this.$refs.ruleForm.validateField('checkPass');
          }
          callback();
        }
      };
      var validatePass2 = (rule, value, callback) => {
        if (value === '') {
          callback(new Error('请再次输入密码'));
        } else if (value !== this.ruleForm.pass) {
          callback(new Error('两次输入密码不一致!'));
        } else {
          callback();
        }
      };
      return {
        ruleForm: {
          pass: '',
          checkPass: '',
          age: ''
        },
        rules: {
          pass: [
            { validator: validatePass, trigger: 'blur' }
          ],
          checkPass: [
            { validator: validatePass2, trigger: 'blur' }
          ],
          age: [
            { validator: checkAge, trigger: 'blur' }
          ]
        }
      };
    },
    methods: {
      submitForm(formName) {
        this.$refs[formName].validate((valid) => {
          if (valid) {
            alert('submit!');
          } else {
            console.log('error submit!!');
            return false;
          }
        });
      },
      resetForm(formName) {
        this.$refs[formName].resetFields();
      }
    }
  }
</script>

核心代码

rules: {
 pass: [
    { validator: validatePass, trigger: 'blur' }
  ],
  checkPass: [
    { validator: validatePass2, trigger: 'blur' }
  ],
  age: [
    { validator: checkAge, trigger: 'blur' }
  ]
}

这段代码可以完成密码一致性的实时校验、但是在线上需求中,不仅要校验一致性、还要通过正则校验密码文本的字符等

优化成js工具类引用即可注入校验规则

JS代码

let passwordValid = [
    {required: true, message: '请输入密码', trigger: ['change', 'blur']},
    {pattern: /^[a-zA-Z0-9_@$^!~,.*]{4,20}$/, message: '密码仅允许数字、字母、下划线、特殊字符,4到20位', trigger: ['change', 'blur']},
]
let equalsCache = {}
let validEquals = (rule, value, callback) => {
    let key = rule.meta.groupId + '-' + (rule.meta.tag === true)
    let otherKey = rule.meta.groupId + '-' + (rule.meta.tag === false)
    equalsCache[key] = value
    if (rule.meta.tag === true && equalsCache[otherKey]) {
        if (equalsCache[otherKey] !== equalsCache[key]) {
            callback(new Error(rule.message));
            return
        }
    }
    callback()
};
let textEqualsValid = (groupId, tag, message) => {
    return [{validator: validEquals, trigger: 'blur', message: message, meta: {groupId: groupId, tag: tag}}]
}
export const CommValidation = {
    /**
     * 密码格式验证
     */
    passwordValid: passwordValid,
    /**
     * 文本一致性验证
     */
    textEqualsValid: textEqualsValid,
}

这个js工具类提供两个功能、一个是密码格式验证,一个是两个文本框是否一致

这里有个比较难处理的问题,每个单独的表单项验证体系中,不会存储另一个表单项的值,所以我采用了equalsCache 表来共享数据,一方面解耦了vue的依赖,另一方面由于cache会存放表单明文值,如果不清理可能造成安全隐患,这里本质上不好清理,因为js类中没有很好的理由提供回调,这样代码就太丑了。因为我们可以通过数据签名来验证数据的一致性,从而保证了明文数据不被保存。

关于上述的问题为何我要纠结明文数据在web页面"存储"的安全性,从概率来讲,将明文数据缓存在浏览器内存的命中概率不高,第一:页面的生命周期不长、第二:此操作的频繁性低。但是这样的操作依然是安全隐患。这相关Web页面的计算机安全问题,暂时不讨论太多,我们作为开发只要保证,尽可能减少敏感数据的传输、存储即可,这里的存储应该是广义的,即信息被某种载体记录。此载体可以是硬盘、文件、内存、大脑、等等。在传输信号时载体的记录形式在发生跃迁,这此跃迁过程中,信号随时可能被窃取并以不为人知的方式存储了下来。

代码简化

rules: {
  pass:CommValidation.passwordValid.concat(CommValidation.textEqualsValid('InfoPwd',false,'两次密码不一致!')),
  checkPass: CommValidation.passwordValid.concat(CommValidation.textEqualsValid('InfoPwd',true,'两次密码不一致!')),
  age: [
    { validator: checkAge, trigger: 'blur' }
  ]
}

最后谈谈这个js放哪里

写代码最头疼的两问,这段代码叫啥名字、这段代码放哪里。关于命名、项目结构也就不多谈了,这玩意太复杂,我也不太懂,我只知道一切需要规范、规约、原则、这样才能得心应手的搬砖。

作为验证工具类,

  • 与项目相关性不大的验证策略:身份证、手机号、出生日期等这些比较固定的验证策略,这种我们应该放在与项目同级的工具包中,即这些代码也可以提供给其他项目使用。当然手机号这玩意的验证也是特复杂。

  • 验证策略与项目相关的。比如密码验证、用户名验证、等等。这种由于和项目耦合我们应该放在项目的validation文件夹中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值