记Element-plus新增触发el-form的rule校验,修改不触发 的解决方案

79 阅读2分钟

1. 问题现象

(1)新增的时候鼠标离开输入框触发el-input输入框的校验

image.png

校验的代码如下


export function validatorNum(rule, value, callback){

  if (value) {

    if (!/^[+]{0,1}(\d+)$|^[+]{0,1}(\d+\.\d+)$/.test(value)) {

      callback(new Error("请输入数字值"));

    }

    if (String(value).indexOf(".") == -1) {

      if (value.length > 8) {

        return callback(new Error(rule.name + "若为整数,不能超过8位"));

      }

    }

    if (String(value).indexOf(".") > -1) {

      if (String(value).split(".")[1].length > 2) {

        return callback(new Error(rule.name + "小数点后不能超过2位"));

      }

      if (String(value).split(".")[0].length > 8) {

        return callback(new Error(rule.name + "小数点前不能超过8位"));

      }

    }

    callback();

  } else {

    callback();

  }

};

(校验规则:小数点前可以输入最多8位,小数点后最多输入2位)

(2)修改已经存入的数据不触发校验

如果数据库中已经存在不合规的数据,点击编辑这条数据,鼠标如果不移入这个el-input框,直接点击确认,不会触发前端el-form的rule校验

image.png

image.png

2. 解决方法

先直接上解决方案,就是修改validatorNum方法


export function validatorNum(rule, val) {

  return new Promise((resolve, reject) => {
    if(val == null || val=="") resolve()

    let value = val.toString();

    if (!/^\[+]{0,1}(\d+)$|^[+]{0,1}(\d+\.\d+)$/.test(value)) {

      reject('请输入数字值');

    }

    if (value.indexOf('.') == -1) {

      if (value.length > 8) {

        reject(rule.name + '若为整数,不能超过8位');

      }

    }

    if (value.indexOf('.') > -1) {

      if (value.split('.')\[1].length > 2) {

        reject(rule.name + '小数点后不能超过2位');

      }

      if (value.split('.')\[0].length > 8) {

        reject(rule.name + '小数点前不能超过8位');

      }

    }

    resolve();

  });

};

再次修改这条数据,直接点击确认,就会触发rule校验

image.png

3.解决思路

当测试提出问题的时候,首先想的就是去Element-plus官网看看是不是自己使用错了

image.png

image.png 发现并没有,但是发现一个有意思的地方,有个校验使用了setTimeout方法包裹,为什么要使用这个呢,因为validator方法返回的是一个Promise

image.png 那么具体查看rules的介绍

image.png 原来它内部使用了第三方库async-validator 我们看看这个库,它的示例里面有这样一个例子

image.png 我们借鉴一下,改造一下我们的validatorNum方法,让它也返回一个Promise

export function validatorNum(rule, val) {

  return new Promise((resolve, reject) => {

    let value = val.toString();

    if (!/^\[+]{0,1}(\d+)$|^[+]{0,1}(\d+\.\d+)$/.test(value)) {

      reject('请输入数字值');

    }

    if (value.indexOf('.') == -1) {

      if (value.length > 8) {

        reject(rule.name + '若为整数,不能超过8位');

      }

    }

    if (value.indexOf('.') > -1) {

      if (value.split('.')\[1].length > 2) {

        reject(rule.name + '小数点后不能超过2位');

      }

      if (value.split('.')\[0].length > 8) {

        reject(rule.name + '小数点前不能超过8位');

      }

    }

    resolve();

  });

};

至此,问题解决