木灵鱼儿

木灵鱼儿

阅读:997

最后更新:2021/04/28/ 16:04:44

element input异步校验+自定义错误提示

主要的效果就是用户注册时,输入的账号如果已经注册了,要提示已经注册,然后提供一个按钮,直接前往登陆。

效果图

教程

首先我们要知道怎么进行自定义错误提示

<template>
   <el-form :model="form" :rules="rules" ref="ruleForm">
    <el-form-item prop="account">
      <el-input v-model="form.account" name="account" placeholder="请输入手机号" autocomplete="on">
       <!-- 自定义错误信息 -->
        <template slot="error" slot-scope="{error}">
          <div class="my-error">
            <div v-if="error==='9001'" class="el-form-item__error">
              您的手机已注册
              <router-link class="link" :to="{name:'Login'}">立即登陆</router-link>
            </div>
            <div v-else class="el-form-item__error">{{error}}</div>
          </div>
        </template>
     </el-form-item>
  </el-form>
</template>

el-form-item中有一个error插槽,通过slot-scope="{error}"可以解构获取到error错误信息。

由于error值是一个string值,所以我们如果想自定义错误提示,就需要判断,我的做法是我自己定义一个错误信息值,一般数字,比如上面的9001。当然了,他还是一个string类型。

这样自定义错误提示就有了,现在就是要处理验证。

异步校验

本来element用的async-validator库,他是有一个异步校验的方法的asyncValidator,可惜框架并不支持,用了也没反应。

所以只能通过validator来使用了。

首先我们在data方法中写一个异步校验的方法:

//验证手机号是否已注册
let oldErrorValue = "";
let isPhoneRegister = async (rule, value, callback) => {
    try {
        if (value === oldErrorValue) {
            return callback(new Error("9001"));
        } else {
            const postData = { phone: value };
            const { data } = await api(postData); //axios请求
            if  (data.is_exist  ===  1)  {
                //错误码是自己定的
                oldErrorValue = value;
                return  callback(new  Error("9001"));
            } 
            else  {
                oldErrorValue = "";
                return  callback();
            }
        }
    } catch (error) {
        callback(error);
    }
};

oldErrorValue 的作用是,当两次输入的值都是一样的,并且是不通过的,那么就不需要再走api判断了。

为了节省资源,我们还可以使用防抖

//防抖
isPhoneRegister = _.debounce(isPhoneRegister, 200);

这里采用的是lodash的防抖方法。

完整代码

<template>
   <el-form :model="form" :rules="rules" ref="ruleForm">
    <el-form-item prop="account">
      <el-input v-model="form.account" name="account" placeholder="请输入手机号" autocomplete="on">
       <!-- 自定义错误信息 -->
        <template slot="error" slot-scope="{error}">
          <div class="my-error">
            <div v-if="error==='9001'" class="el-form-item__error">
              您的手机已注册
              <router-link class="link" :to="{name:'Login'}">立即登陆</router-link>
            </div>
            <div v-else class="el-form-item__error">{{error}}</div>
          </div>
        </template>
     </el-form-item>
  </el-form>
</template>
<script>
import { api } from "../../api/login";
import _ from "lodash";
export default {
  data() {
    //验证手机号是否已注册
    let oldErrorValue = "";
    let isPhoneRegister = async (rule, value, callback) => {
        try {
            if (value === oldErrorValue) {
                return callback(new Error("9001"));
            } else {
                const postData = { phone: value };
                const { data } = await api(postData); //axios请求
                if  (data.is_exist  ===  1)  {
                    //错误码是自己定的
                    oldErrorValue = value;
                    return  callback(new  Error("9001"));
                } 
                else  {
                    oldErrorValue = "";
                    return  callback();
                }
            }
        } catch (error) {
            callback(error);
        }
    };
    return {
      form:{
        account:"",
      },
      rules:{
        account:[
          { required: true, message: "请输入手机号", trigger: "blur" },
          //这里最好再加一个验证手机号是否合法的验证:数字11位
          { validator: isPhoneRegister, trigger: ["change", "blur"] },
        ]
      }
    }
  }
}
</script>

缺点

饿了么的验证,如果采用了自定义校验,如果验证的速度够快,网页上的错误提示不会重新显示,如果验证速度慢的话,就会导致相同的错误,先消失,然后再显示。

目前找不到啥解决办法,不过也无伤大雅,如果想减少这个情况,可以把change触发方式去除,只留blur事件。

版权申明

本文系作者 @木灵鱼儿 原创发布在木灵鱼儿 - 有梦就能远航站点。未经许可,禁止转载。

关于作者

站点职位 博主
获得点赞 0
文章被阅读 997

相关文章