【Vue3】通用表单校验的两种方式


1. 表单校验需求

1.1 动作触发校验

最常用的就是光标离开输入框时进行单个输入框的校验,如下:

在这里插入图片描述

1.2 点击按钮校验

还有一种就是点击按钮时进行整个表单的校验,比如登录时,检查表单所有输入内容是否合法。当不合法时,显示Toast提示信息。

在这里插入图片描述

2. 实现

使用的是Vant UI,其他的框架如Element-plus也是一个道理:

2.1 实现单个输入框校验

需要给输入框添:

  • 加一个rules,里面内容是一个规则列表,主要有两种,一种是通过正则校验,另一种是通过自定义验证器校验
  • 添加name属性,值为对应的校验对象的名字

rules说明:

  • pattern:通过正则表达式进行校验,正则无法匹配表示校验不通过
  • message:错误提示文案,可以设置为一个函数来返回动态的文案内容
  • validator:通过函数进行校验,可以返回一个 Promise 来进行异步校验
  • trigger:设置本项规则的触发时机,优先级高于 Form 组件设置的 validate-trigger 属性,可选值为 onChange、onBlur、onSubmit。默认是onBlur,即光标离开时触发
<van-form ref="loginFormRef">
    <van-cell-group inset>
        <!-- 通过 pattern 进行正则校验 -->
        <van-field v-model="formData.email" label="邮箱" name="emailPattern" placeholder="请输入邮箱"
            :rules="[{ pattern: emailPattern, message: '请输入正确邮箱' }]" />
        <!-- 通过 validator 进行函数校验 -->
        <van-field v-model="formData.password" label="密码" name="passwordValidator" placeholder="请输入密码" type="password"
            :rules="[{ validator: passwordValidator, message: '密码应为字母,数字,特殊符号,两种及以上组合,8-16位字符串' }]" />
    </van-cell-group>
</van-form>

<script setup>
// 校验函数返回 true 表示校验通过,false 表示不通过
const emailPattern = /^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(.[a-zA-Z0-9_-]+)+$/;
const passwordValidator = (val) => /(?!^(\d+|[a-zA-Z]+|[~!@#$%^&*()_.]+)$)^[\w~!@#$%^&*()_.]{6,20}$/.test(val);
</script>

2.2 点击按钮时整体校验

Form标签添加ref,在script中定义该对象,给按钮添加@click,点击时触发函数

在函数中,使用ref中的对象.value?validate()进行校验

validate()中无参数默认校验整个表单

<van-form ref="loginFormRef">
	<van-button round block type="primary" @click="handleLogin">登录 </van-button>
</van-form>
<script setup>
const loginFormRef = ref();

function handleLogin() {
      
      
    loginFormRef.value?.validate(['emailPattern', 'passwordValidator']).then(() => {
      
      
        // 验证通过
      
    }).catch((err) => {
      
      
        //验证失败
        showFailToast('请正确填写信息');
    })
}
</script>

3. 完整代码

<template >
    <div class="page_wrap">
        <div class="form_wrap">
            <van-row>
                <van-col span="24" style="font-size: 30px;text-align: center;margin: 0 0  30px 0;">{
   
   { pageName }}</van-col>
            </van-row>
            <hr style="margin-top: -20px;">
            <van-row style="padding: 20px 15px;margin-top: -10px;" justify="space-between">
                <van-col span="11"><van-button plain type="primary" style="width:95%"
                        @click="changePageName('求职人员登录')">求职人员登录</van-button></van-col>
                <van-col span="11"><van-button plain type="primary" style="width:95%"
                        @click="changePageName('招聘人员登录')">招聘人员登录</van-button></van-col>
            </van-row>
            <van-form ref="loginFormRef">
                <van-cell-group inset>
                    <!-- 通过 pattern 进行正则校验 -->
                    <van-field v-model="formData.email" label="邮箱" name="emailPattern" placeholder="请输入邮箱"
                        :rules="[{ pattern: emailPattern, message: '请输入正确邮箱' }]" />
                    <!-- 通过 validator 进行函数校验 -->
                    <van-field v-model="formData.password" label="密码" name="passwordValidator" placeholder="请输入密码"
                        autocomplete="false" type="password"
                        :rules="[{ validator: passwordValidator, message: '密码应为字母,数字,特殊符号,两种及以上组合,8-16位字符串' }]" />
                </van-cell-group>
                <van-row style="padding: 20px 15px;margin-top: 10px;">
                    <van-col span="24">
                        <p class="forgetPassword" align="right" style="cursor: pointer;"
                            @click="router.push('/resetpassword')">忘记密码?</p>
                    </van-col>
                </van-row>
                <div style="margin-top: -30px;padding:0 15px; 0 15px">
                    <van-button round block type="primary" @click="handleLogin">登录 </van-button>
                    <van-button round block plain style="margin-top: 10px;" @click="router.push('/register')">注册</van-button>
                </div>
            </van-form>
        </div>
    </div>
</template>
<script setup>
import {
    
     ref, reactive } from 'vue';
import {
    
     showFailToast, showLoadingToast } from 'vant';
import router from '@/router';
import {
    
     login } from '@/utils/request';
import store from '@/store';

const loginFormRef = ref();
const pageName = ref('求职人员登录');
const formData = reactive({
    
    
    email: '',
    password: '',
    roleName: '求职者'
})
// 校验函数返回 true 表示校验通过,false 表示不通过
const emailPattern = /^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(.[a-zA-Z0-9_-]+)+$/;
const passwordValidator = (val) => /(?!^(\d+|[a-zA-Z]+|[~!@#$%^&*()_.]+)$)^[\w~!@#$%^&*()_.]{6,20}$/.test(val);

function changePageName(name) {
    
    
    pageName.value = name
    if ('求职人员登录' == name) {
    
    
        formData.roleName = '求职者'
    } else {
    
    
        formData.roleName = '招聘者'
    }
}

function handleLogin() {
    
    
    loginFormRef.value?.validate(['emailPattern', 'passwordValidator']).then(() => {
    
    
        // 验证通过
        login(formData).then(res => {
    
    
            if (res.data.code == 200) {
    
    
                // 响应成功
            } else {
    
    
                // 响应失败
                showFailToast(res.data.message || '服务器出错')
            }
        })
    }).catch((err) => {
    
    
        //验证失败
        showFailToast('请正确填写信息');
    })
}
</script>

猜你喜欢

转载自blog.csdn.net/happy488127311/article/details/129611113