一.实现思路与效果图

使用async-validator 插件,阿里出品的 antdElementUI 组件库中表单校验默认使用的 async-validator

效果图:在这里插入图片描述

二.实现具体过程

  1. npm i async-validator -S

  2. 绑定loginForm

    const loginForm = reactive({
      username: "",
      password: "",
    });
    
  3. 初始化检验规则和错误提示

// 校验规则
const descriptor = reactive({
  username: {
    required: true,
    message: "账号不能为空",
  },
  password: [
  // 多条校验规则
    {
      required: true,
      message: "密码不能为空",
    },
    {
      validator(rule, value, callback) {
        value < 12 ? callback(new Error("不能少于12位")) : callback();
      },
    },
  ],
});
  1. created里实例化构造函数表示创建一个校验器,参数为校验规则对象

    const validator = reactive(new Schema(descriptor));
    
  2. 定义提交的方法

       const submit = () => {
                this.clearMessage()
                validator.validate(this.form, {
                    firstFields: true
                }).then(() => {
                    // 校验通过
                    console.log('ok')
                }).catch(({ errors }) => {
                    // 校验未通过
                    // 显示错误信息
                    for (let { field, message } of errors)                   this.errorMessage[field] = message
                })
            },
    
    • clearMessage // 清空校验错误提示

      const clearMessage = () => {
        for (let key in errorMessage) {
          errorMessage[key] = "";
        }
      };
      
    • validate方法

      验证器对象的validate方法用于验证数据是否符合验证规则。

      如验证一个空对象,是否符合验证规则

      function(source, [options], callback): Promise
      

      参数:

      • source 要验证的对象(必选)
      • [options] 验证处理选项对象(可选)
      • callback 验证完成时调用的回调函数(可选)

      options的配置

      {
        suppressWarning: false, // 是否禁止无效值的内部警告
        first: false, // 是否在第一个规则验证错误时调用回调,不再处理其他验证规则
        firstFields: true // 是否在指定字段的第一个规则验证错误时调用回调,不再处理相同字段的验证规则,true代表所有字段
      }
      
      
    • 返回值:
      validate方法返回一个promise对象,可以用then方法和catch方法绑定成功或失败的处理

      validator.validate({})
        .then(() => {
          console.log('验证通过')
        })
        .catch(({ errors, fields }) => {
        console.log('验证不通过', errors, fields)
      })
      
      
  3. 使用v-bind控制输入框红色的显隐藏 :class="{ checkusername: isActiveUsername }"如果为空则显示红色

三.完整代码与效果图

  1. 完整代码

    <template>
      <div class="main">
        <h3>Vue3表单验证</h3>
    
        <div class="form-box">
          <div class="form-group">
            <label class="label">账号</label>
            <input
             :class="{ checkusername: isActiveUsername }"
              type="text"
              v-model="loginForm.username"
              class="input"
              placeholder="请输入账号"
            />
            <span class="check-message">{{ errorMessage.username }}</span>
          </div>
          <div class="form-group">
            <label class="label">密码</label>
            <input
              :class="{ checkpassword: isActivePassword }"
              tyep="password"
              v-model="loginForm.password"
              type="text"
              placeholder="请输入密码"
              class="input"
            />
            <span class="check-message">{{ errorMessage.password }}</span>
          </div>
    
          <div class="form-group">
            <button class="btn" @click="submit()">保存</button>
          </div>
        </div>
      </div>
    </template>
    
    <script setup>
    import Schema from "async-validator";
    import { reactive,ref } from "vue";
    //控制输入框变红
    const isActiveUsername = ref(false)
    const isActivePassword = ref(false)
    // 表单对象
    const loginForm = reactive({
      username: "",
      password: "",
    });
    // 校验规则
    const descriptor = reactive({
      username: {
        required: true,
        message: "姓名不能为空",
      },
      password: [
        {
          required: true,
          message: "密码不能为空",
        },
      ],
    });
    // 错误提示
    const errorMessage = reactive({
      username: "",
      password: "",
    });
    const validator = reactive(new Schema(descriptor));
    const submit = () => {
       if (loginForm.username === '') {
        isActiveUsername.value = true
      }
      if (loginForm.password === '') {
        isActivePassword.value = true
      }
      if (loginForm.username != '') {
        isActiveUsername.value = false
      }
      if (loginForm.password != '') {
        isActivePassword.value = false
      }
      clearMessage();
      validator
        .validate(loginForm, {
          firstFields: true,
        })
        .then(() => {
          // 校验通过
          console.log(" 校验通过,可以发起请求");
        })
        .catch(({ errors }) => {
          // 校验未通过
          // 显示错误信息
          for (let { field, message } of errors) errorMessage[field] = message;
        });
    };
    // 清空校验错误提示
    const clearMessage = () => {
      for (let key in errorMessage) {
        errorMessage[key] = "";
      }
    };
    </script>
    
    <style scoped>
    .main {
      text-align: center;
    }
    .btn {
      margin: 0;
      line-height: 1;
      padding: 15px;
      height: 30px;
      width: 60px;
      font-size: 14px;
      border-radius: 4px;
      color: #fff;
      background-color: #2080f0;
      white-space: nowrap;
      outline: none;
      position: relative;
      border: none;
      display: inline-flex;
      flex-wrap: nowrap;
      flex-shrink: 0;
      align-items: center;
      justify-content: center;
      user-select: none;
      text-align: center;
      cursor: pointer;
      text-decoration: none;
    }
    .form-box {
      width: 500px;
      max-width: 100%;
      margin: 0 auto;
      padding: 10px;
      border: 5px solid rgb(171 174 186);
    }
    .form-group {
      height: 30px;
      margin: 10px;
      padding: 10px 15px 10px 0;
    }
    .label {
      padding-right: 10px;
      padding-left: 10px;
      display: inline-block;
      box-sizing: border-box;
      width: 110px;
      text-align: right;
    }
    
    .input {
      width: calc(100% - 120px);
      height: 28px;
    }
    .check-message {
      color: #d03050;
      position: relative;
      left: -70px;
    }
    .checkpassword,
    .checkusername {
      border: 2px solid #d03050 !important ;
    }
    </style>
    

参考链接:https://github.com/tmpfs/async-validate

https://www.cnblogs.com/wozho/p/10955525.html

Logo

基于 Vue 的企业级 UI 组件库和中后台系统解决方案,为数万开发者服务。

更多推荐