基于 Vue3 和 Element Plus 的 validate 的使用

99 阅读2分钟

在日常开发中,我们常常需要在表单中对用户输入进行接口校验。比如,某个输入框输入完成后,需要调用接口判断是否合法,再决定是否获取联动数据。

本文将围绕以下业务场景,深入讲解如何正确使用 validator 配合节流/防抖和异步接口校验,避免校验失效的问题。

1、业务场景说明

一个输入框(或下拉框),用户输入后需要:

  1. 调用接口校验输入值是否合法;
  2. 若合法,继续调用另一个接口获取后续联动数据;
  3. 并且,该输入框是被其他表单项依赖的,需要及时触发校验和数据更新。

初始方案:使用 blur 触发校验

{ validator: validatePass2, trigger: 'blur' }

这在大多数表单项中是常规写法。用户输入完成后失焦,触发 validatePass2 方法,完成接口验证。

问题: 如果该字段被其他字段依赖,用户不失焦就不会触发校验,从而影响联动逻辑。

改进方案:使用 change 触发

{ validator: validatePass2, trigger: 'change' }

这样一旦输入变化就触发校验,可以即时联动。

新问题来了:

  • 只要用户输入,就会不断触发接口请求;
  • 输入较快时频繁请求,接口压力变大,性能下降。

进一步优化:引入节流或防抖

{ validator: debounce(validatePass2, 500), trigger: 'change' }
const validatePass2 = debounce((rule, value, callback) => {
  // 异步请求
}, 500)

这边不知道为什么第二种不可以,有知道的大佬看回复一下

校验失效:async/await + validator 的陷阱

const validatePass2 = async (rule, value, callback) => {
  const res = await apiValidate(value);
  if (res.valid) {
    callback();
  } else {
    callback(new Error('输入不合法'));
  }
}

看起来没问题,但有些场景下表单项永远处于“校验中”状态,或者根本不触发 callback,直接导致表单验证失败或失效。

const validatePass2 = (rule, value, callback) => {
  apiValidate(value).then(res => {
    if (res.valid) {
      callback();
    } else {
      callback(new Error('输入不合法'));
    }
  }).catch(() => {
    callback(new Error('验证失败'));
  });
}

最后只能修改成这样子

欢迎大家留言探讨你们的实践经验,如有疏漏或不妥之处,欢迎在评论区指出,互相学习,共同进步!