0

0

vue3+async-validator如何实现表单验证

PHPz

PHPz

发布时间:2023-05-11 09:55:12

|

3692人浏览过

|

来源于亿速云

转载

    搭建vue3的项目

    创建项目前 这里我们首先要说明的是,我们使用的版本情况

    • Nodejs:v17.5.0

    • pnpm:7.0.0

    • Vue:3.2.25

    首先我们 Vite 创建一个 vue3 的项目demo,名字就叫 FormValidate, 我们在命令行输入命令

    立即学习前端免费学习笔记(深入)”;

    pnpm create vite FormValidate 回车

    然后选择 vue

    继续回车,说明我们已经初步创建了 FormValidate (表单验证)项目

    根据命令行的提示,我们进入项目根目录,然后使用命令 pnpm install 安装项目需要的依赖,当然这里使用 pnpm 是比 npm 或者 yarn 快很多的。

    接着,我们启动项目 pnpm run dev, 终端中输出如图内容

     vite v2.9.7 dev server running at:
      > Local: http://localhost:3000/
      > Network: use `--host` to expose
      ready in 954ms.

    启动浏览起,输入地址 http://localhost:3000/

    ok, 到这里我们已经把项目搭建起来了,结下来我们就开始来说说我们今天主题-表单验证

    vue3的表单验证

    这里我们使用 async-validator 这是个异步验证表单的插件,在github上有 5k+ 的star,使用的也很广泛,比如 Ant.designElement UINaive UI 等都在使用这个插件,甚至与有些Nodejs后端项目也在使用这个。

    先安装一下这个插件,在命令行输入

    pnpm install async-validator

    这里 async-validator 版本是 4.1.1

    1.表单代码

    打开项目中的 App.vue 文件,删除多余的文件内容,输入标题 vue3 表单验证,并添加一些初始代码

    <template>
        <div class="main">
            <h4>vue3 表单验证</h4>
    
            <form>
                <div>
                    <label class="label">账号</label>
                    <input  type="text"  placeholder="请输入账号" class="input" />
                </div>
                <div>
                    <label class="label">密码</label>
                    <input  tyep="password" type="text" class="input"  placeholder="请输入密码"  />
                </div>
    
                <div>
                    <button>保存</button>
                </div>
            </form>
        </div>
    </template>
    <script setup>
    
    </script>
    <style lang="css">
    .main{
        text-align:center;
    }
    .label {
        padding-right: 10px;
        padding-left: 10px;
        display: inline-block;
        box-sizing: border-box;
        width: 100px;
        text-align: right;
    }
    .input {
        width: 200px;
        height: 30px;
        margin-top:10px;
    }
    </style>

    是不是看起来有点丑,别急,我们加点css代码,简单的美化一下

    <template>
        <div class="main">
            <h4>Vue3表单验证</h4>
    
            <form class="form-box">
                <div class="form-group ">
                    <label class="label">账号</label>
                    <input type="text" class="input" placeholder="请输入账号"  />
                </div>
                <div class="form-group">
                    <label class="label">密码</label>
                    <input  tyep="password" type="text"  placeholder="请输入密码" class="input" />
                </div>
    
                <div class="form-group">
                    <button class="btn ">保存</button>
                </div>
            </form>
        </div>
    </template>
    <script setup>
    
    </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;
    }
    .form-group{
        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;
    }
    </style>

    2.添加验证

    2-1. 初始化

    引入ref 属性和 async-validator,这里我们给每个 input 框添加 v-model 绑定属性,

    // html
    <input type="text" v-model="form.account" class="input" placeholder="请输入账号"  />
    <input  tyep="password" v-model="form.password" type="text"  placeholder="请输入密码" class="input" />
    // script
    import { ref } from "vue"
    import Schema from 'async-validator';
    
    const form = ref({
        account: null,
        password: null,
    })

    根据表单的情况,我们定义一个对象,这个对象里面存储了需要校验的对象和校验不通过时的信息

    const rules = {
        account: { required: true, message: '请输入账号' },
        password: { required: true, message: '请输入密码' }
    }

    实例化 Schema, 将 rules 传入 Schema,得到一个 validator

    const validator = new Schema(rules)

    验证单个表单我们使用 失去焦点事件, 定义一个函数,将这个函数添加到 account input上的失焦事件上

    // html
    <input v-model="account" type="text" class="input" @blur="handleBlurAccount" placeholder="请输入账号"  />
    // script
    const handleBlurAccount = () => {}

    接着将实例化后的校验器函数写到 handleBlurAccount 中

    const handleBlurAccount = () => {
        validator.validate({account: form.value.account}, (errors, fields) => {
            if (errors && fields.account) {
                console.log(fields.account[0].message);
                return errors
            }
        })
    }

    在account 的 input 中测试,我们可以看到在控制台打印出了 请输入账号 等字

    Otter.ai
    Otter.ai

    一个自动的会议记录和笔记工具,会议内容生成和实时转录

    下载

    同样的,我们给密码框也添加如下代码

    //html
    <input v-model="form.password" tyep="password" type="text" @blur="handleBlurPassword"  placeholder="请输入密码" class="input" />
    //script
    const handleBlurPassword = () => {
        validator.validate({password: form.value.password}, (errors, fields) => {
            if (errors && fields.password) {
                console.log(errors, fields);
                console.log(fields.password[0].message);
                return errors
            }
        })
    }
    2-2. 多个表单的验证

    当然这里校验的只是单个input的,我们接下来说说多个表单的校验,定义一个点击事件为submit,将submit事件添加到button上,当然不要忘记阻止浏览器默认事件

    const submit = (e) => {
        e.preventDefault();
        validator.validate(form.value, (errors, fields) => {
            if (errors) {
                for(let key of errors) {
                    console.log(key.message);
                }
                return errors
            }
        })
    }
    2-3. Promise方式验证

    了上面的方式,async-validator 还提供 Promise 的方式,我们把 submit 函数中的代码修改为如下

    validator.validate(form.value).then((value) => {
            // 校验通过
            console.log(value);
    }).catch(({ errors, fields }) => {
        console.log(errors);
        return errors
    })

    点击保存,同样的,我们可以看到控制台已经打印了错误信息,说明我们写的是合适的

    vue3+async-validator如何实现表单验证

    2-4. 正则验证

    当然有时候我们会输入邮箱,电话号码等表单,这时候我们就需要添加正则来进行验证了,我们先添加两个表单,并添加失焦事件, 正则验证需要用到 async-validator 的属性 pattern,我们将符合要求的正则添加到 rules ,代码如下所示

    <div class="form-group ">
        <label class="label">电话号码</label>
        <input v-model="form.phone" type="text" class="input" @blur="handleBlurPhone"
                        placeholder="请输入电话号码" />
    </div>
    
    <div class="form-group ">
        <label class="label">邮箱</label>
        <input v-model="form.email" type="text" class="input" @blur="handleBlurEmail"
                        placeholder="请输入邮箱" />
    </div>
    
    
    const form = ref({
        account: null,
        email: null,
        password: null,
    })
    
    const rules = {
        account: { required: true, message: '请输入账号' },
        phone: {
            required: true,
            pattern: /^1\d{10}$/,
            message: "请输入电话号码"
        },
        email: {
            required: true,
            pattern: /^([a-zA-Z0-9]+[_|_|\-|.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|_|.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,6}$/,
            message: "请输入邮箱"
        },
        password: { required: true, message: '请输入密码' }
    }
    
    const handleBlurPhone = () => {
        validator.validate({ phone: form.value.phone }, (errors, fields) => {
            if (errors && fields.phone) {
                console.log(errors, fields);
                console.log(fields.phone[0].message);
                return errors
            }
        })
    }
    const handleBlurEmail = () => {
        validator.validate({ email: form.value.email }, (errors, fields) => {
            if (errors && fields.email) {
                console.log(errors, fields);
                console.log(fields.email[0].message);
                return errors
            }
        })
    }

    当然,测试是没有问题的

    2-5. 长度控制

    假如你要控制表单输入内容的长度,可以使用属性 min 和 max,我们用 account 这个表单作为例子,我们 rules 对象的 account 中添加这两个属性,比如要求账号最少5个字符,最多10个字符,如下

    account: { required: true, min:5, max:10, message: '请输入账号' }

    我们还可以使用 input 的原生属性 maxLength="10" 来控制用户的输入

    2-6. 多个验证条件

    当我们有多个验证条件的时候,我们可以把 rules 的验证条件写成一个数组,我们还是用 account 这个表单作为例子,比如 账号要求必须用中文,且账号最少5个字符,最多10个字符,代码如下

    account: [
        { required: true, min:5, max:10, message: '请输入账号' },
        { required: true, pattern: /[\u4e00-\u9fa5]/, message: '请输入中文账号' }
    ],
    2-5. 自定义验证

    有时候,我们会有使用自定义验证函数的情况,以满足特殊验证情况,这时候,我们可以这样做

    field:{
        required: true,
        validator(rule, value, callback){
          return value === '';
        },
        message: '值不等于 "".',
    }

    到这里,vue3的表单验证功能雏形已经基本出来了,下面我们对验证功能进行完善

    3.优化完善

    之前的表单验证虽然已经做出了,但是校验的提示信息是在控制台,这个很不友好,用户也看不到提示,所以这里我们完善下这部分功能

    首先我们在 label 边加一个 "*" 表示必填,并且添加样式,给一个红色,醒目一些

    <label class="label">
        <span>账号</span>
        <span class="asterisk"> *</span>
    </label>
    .asterisk{
        color: #d03050;
    }

    我们考虑到 rules 对象中 required 属性的作用,这里使用 vue 的条件判断语句 v-if 来判断,先定义一个函数,名字就叫 getRequired,然后将 rules.account,作为参数传进去,这里要重点说明一下,如果考虑封装验证方法,这里可以不用传参,不多说,后面讲到了,我们再说,先看代码

     <span class="asterisk" v-if="getRequired(rules.account)"> *</span>
    const getRequired = (condition) => {
        if(Object.prototype.toString.call(condition) === "[object Object]") {
            return condition.required
        } else if (Object.prototype.toString.call(condition) === "[object Array]") {
            let result = condition.some(item => item.required)
            return result
        }
        return false
    }

    因为 rules.account, 有可能是对象或者数组,这里我们加一个判断区别下,如果传递进来的是对象,我们直接将属性required返回回去,至于required属性是否存在,这里没有必要多判断。 如果传递进来的是数组,我们使用 some 函数获取下结果,然后再返回.

    修改 rules.accountrequired 值为false,星号消失,这里只要有一个required 值为true,那么这个星号就显示

    我们接着来添加错误信息的显示与隐藏

    我们定义一个对象 modelControl,这个对象里面动态存储错误信息,

    const modelControl = ref({})

    接着给 accountinput 框添加一个自定义属性 prop, 属性值是 account, 再加一个div显示错误提示信息

    <div class="form-group">
        <label class="label">
            <span>账号</span>
            <span class="asterisk" v-if="getRequired(rules.account)"> *</span>
        </label>
        <input v-model="form.account" type="text" maxLength="10" class="input" prop="account" @blur="handleBlurAccount" placeholder="请输入账号" />
        <div class="input feedback" v-if="modelControl['account']">{{modelControl['account']}}</div>
    </div>
    
    .feedback{
        color: #d03050;
        font-size:14px;
        margin-top: 3px;
        text-align:left;
        margin-left:110px;
    }

    为了动态的显示和隐藏错误信息,我们需要修改失焦事件 和 submit 事件,在事件执行的时候,动态的将值赋予或清除,代码如下

    const handleBlurAccount = (e) => {
        const prop = e.target.attributes.prop.value
        if (!prop) {
            return false
        }
        validator.validate({ account: form.value.account }, (errors, fields) => {
            if (errors && fields.account) {
                console.log(errors, fields);
                console.log(fields.account[0].message);
    
                modelControl.value[prop] = fields[prop][0].message
                return errors
            }
            modelControl.value[prop] = null
        })
    }
    validator.validate(form.value).then((value) => {
            // 校验通过
        console.log(value);
    }).catch(({ errors, fields }) => {
        console.log(errors, fields);
        for(let key in fields) {
            modelControl.value[key] = fields[key][0].message
        }
        console.log(modelControl);
        return errors
    })

    到这里 表单的动态验证功能基本算是完成了,但是我们发现,每次错误信息的展示都会使得input框跳动,所以还得调整下样式

    .form-group {
        margin: 2px;
        padding: 10px 15px 3px 0;
        height:57px;
        transition: color .3s ease;
    }

    热门AI工具

    更多
    DeepSeek
    DeepSeek

    幻方量化公司旗下的开源大模型平台

    豆包大模型
    豆包大模型

    字节跳动自主研发的一系列大型语言模型

    WorkBuddy
    WorkBuddy

    腾讯云推出的AI原生桌面智能体工作台

    腾讯元宝
    腾讯元宝

    腾讯混元平台推出的AI助手

    文心一言
    文心一言

    文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

    讯飞写作
    讯飞写作

    基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

    即梦AI
    即梦AI

    一站式AI创作平台,免费AI图片和视频生成。

    ChatGPT
    ChatGPT

    最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

    相关专题

    更多
    if什么意思
    if什么意思

    if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

    847

    2023.08.22

    c语言const用法
    c语言const用法

    const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

    564

    2023.09.20

    promise的用法
    promise的用法

    “promise” 是一种用于处理异步操作的编程概念,它可以用来表示一个异步操作的最终结果。Promise 对象有三种状态:pending(进行中)、fulfilled(已成功)和 rejected(已失败)。Promise的用法主要包括构造函数、实例方法(then、catch、finally)和状态转换。

    337

    2023.10.12

    html文本框类型介绍
    html文本框类型介绍

    html文本框类型有单行文本框、密码文本框、数字文本框、日期文本框、时间文本框、文件上传文本框、多行文本框等等。详细介绍:1、单行文本框是最常见的文本框类型,用于接受单行文本输入,用户可以在文本框中输入任意文本,例如用户名、密码、电子邮件地址等;2、密码文本框用于接受密码输入,用户在输入密码时,文本框中的内容会被隐藏,以保护用户的隐私;3、数字文本框等等。

    429

    2023.10.12

    点击input框没有光标怎么办
    点击input框没有光标怎么办

    点击input框没有光标的解决办法:1、确认输入框焦点;2、清除浏览器缓存;3、更新浏览器;4、使用JavaScript;5、检查硬件设备;6、检查输入框属性;7、调试JavaScript代码;8、检查页面其他元素;9、考虑浏览器兼容性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

    197

    2023.11.24

    github中文官网入口 github中文版官网网页进入
    github中文官网入口 github中文版官网网页进入

    github中文官网入口https://docs.github.com/zh/get-started,GitHub 是一种基于云的平台,可在其中存储、共享并与他人一起编写代码。 通过将代码存储在GitHub 上的“存储库”中,你可以: “展示或共享”你的工作。 持续“跟踪和管理”对代码的更改。

    4303

    2026.01.21

    http500解决方法
    http500解决方法

    http500解决方法有检查服务器日志、检查代码错误、检查服务器配置、检查文件和目录权限、检查资源不足、更新软件版本、重启服务器或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

    497

    2023.11.09

    http请求415错误怎么解决
    http请求415错误怎么解决

    解决方法:1、检查请求头中的Content-Type;2、检查请求体中的数据格式;3、使用适当的编码格式;4、使用适当的请求方法;5、检查服务器端的支持情况。更多http请求415错误怎么解决的相关内容,可以阅读下面的文章。

    452

    2023.11.14

    TypeScript类型系统进阶与大型前端项目实践
    TypeScript类型系统进阶与大型前端项目实践

    本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

    26

    2026.03.13

    热门下载

    更多
    网站特效
    /
    网站源码
    /
    网站素材
    /
    前端模板

    精品课程

    更多
    相关推荐
    /
    热门推荐
    /
    最新课程
    Vue3.x 工具篇--十天技能课堂
    Vue3.x 工具篇--十天技能课堂

    共26课时 | 1.6万人学习

    Vue3.x 核心篇--十天技能课堂
    Vue3.x 核心篇--十天技能课堂

    共30课时 | 1.6万人学习

    Vue3.x新特性篇--十天基础课堂
    Vue3.x新特性篇--十天基础课堂

    共20课时 | 1.3万人学习

    关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
    php中文网:公益在线php培训,帮助PHP学习者快速成长!
    关注服务号 技术交流群
    PHP中文网订阅号
    每天精选资源文章推送

    Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号