今天在学习 Vue 的过程中用到了表单验证功能,这里简单记录下实现过程。
前端页面
登录界面如下所示,要实现的效果为鼠标离开文本框时,文本框自动校验是否满足用户名和密码的校验规则,这里要求的规则是长度为 5~16 非空字符串,如果需要其他规则可按需定义。
自定义校验规则
要实现校验,首先需要定义校验规则,其中 rules 为表单校验规则,其中的 username, password, rePassword 为需要校验的字段。因为这些字段是需要发送给后端的,所以为方便起见,建议和后端传参是的变量名一致。
checkRePassword 需要在 rules 前面定义,否则不生效。
required: true //表示该字段必须要填写
message: ‘请输入用户名’ //表示若没有填写该字段,出现的提示信息
trigger: ‘blur’ //表示当前表单失焦了,该表单就开始校验
min:5 //所需要的最小长度
max: 16 //最大长度
message: ‘长度为5~16位非空字符串’ // 若不满足min 或 max 条件出现的提示信息
// 定义校验密码的规则
<script setup>
const checkRePassword = (rule, value, callback) => {
if (value === '') {
callback(new Error('请再次输入密码'))
}
else if (value !== registerData.value.password) {
callback(new Error('两次输入密码不一致'))
}
else {
callback()
}
}
// 定义表单验证规则
const rules = {
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min:5, max: 16, message: '长度为5~16位非空字符串', trigger: 'blur'}
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 5, max: 16, message: '长度为5~16位非空字符串', trigger: 'blur'}
],
rePassword: [
{ required: true, message: '请再次输入密码', trigger: 'blur' },
{ validator: checkRePassword, trigger: 'blur'}
]
}
</script>
当需要一些复杂的验证条件时也可通过正则表达式来实现,例如
<script setup>
const rules = {
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ pattern: /^(\-|\+)?(((\d|[1-9]\d|1[0-7]\d|0{1,3})\.\d{0,7})|(\d|[1-9]\d|1[0-7]\d|0{1,3})|180\.0{0,6}|180)$/, min:5, max: 16, message: '长度为5~16位非空字符串', trigger: 'blur'}
]
}
</script>
绑定元素
在 标签上添加 :rules 属性,值为上面定义的校验规则名字;在需要校验的表单项里面(这里为)添加 prop 属性,值为相对应的校验规则里面的名字。
<!-- 注册表单 -->
<el-form ref="form" size="large" autocomplete="off" v-if="isRegister" :model="registerData" :rules="rules">
<el-form-item>
<h1>注册</h1>
</el-form-item>
<el-form-item prop="username">
<el-input :prefix-icon="User" placeholder="请输入用户名" v-model="registerData.username"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input :prefix-icon="Lock" type="password" placeholder="请输入密码" v-model="registerData.password"></el-input>
</el-form-item>
<el-form-item prop="rePassword">
<el-input :prefix-icon="Lock" type="password" placeholder="请输入再次密码" v-model="registerData.rePassword"></el-input>
</el-form-item>
<!-- 注册按钮 -->
<el-form-item>
<el-button class="button" type="primary" auto-insert-space>
注册
</el-button>
</el-form-item>
<el-form-item class="flex">
<el-link type="info" :underline="false" @click="isRegister = false">
← 返回
</el-link>
</el-form-item>
</el-form>
效果
完整登录界面代码
<script setup>
import { User, Lock } from '@element-plus/icons-vue'
import { ref } from 'vue'
//控制注册与登录表单的显示, 默认显示注册
const isRegister = ref(false)
// 定义数据模型
const registerData = ref({
username: '',
password: '',
rePassword: ''
})
// 定义校验密码的规则
const checkRePassword = (rule, value, callback) => {
if (value === '') {
callback(new Error('请再次输入密码'))
}
else if (value !== registerData.value.password) {
callback(new Error('两次输入密码不一致'))
}
else {
callback()
}
}
// 定义表单验证规则
const rules = {
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min:5, max: 16, message: '长度为5~16位非空字符串', trigger: 'blur'}
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 5, max: 16, message: '长度为5~16位非空字符串', trigger: 'blur'}
],
rePassword: [
{ required: true, message: '请再次输入密码', trigger: 'blur' },
{ validator: checkRePassword, trigger: 'blur'}
]
}
</script>
<template>
<el-row class="login-page">
<el-col :span="12" class="bg"></el-col>
<el-col :span="6" :offset="3" class="form">
<!-- 注册表单 -->
<el-form ref="form" size="large" autocomplete="off" v-if="isRegister" :model="registerData" :rules="rules">
<el-form-item>
<h1>注册</h1>
</el-form-item>
<el-form-item prop="username">
<el-input :prefix-icon="User" placeholder="请输入用户名" v-model="registerData.username"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input :prefix-icon="Lock" type="password" placeholder="请输入密码" v-model="registerData.password"></el-input>
</el-form-item>
<el-form-item prop="rePassword">
<el-input :prefix-icon="Lock" type="password" placeholder="请输入再次密码" v-model="registerData.rePassword"></el-input>
</el-form-item>
<!-- 注册按钮 -->
<el-form-item>
<el-button class="button" type="primary" auto-insert-space>
注册
</el-button>
</el-form-item>
<el-form-item class="flex">
<el-link type="info" :underline="false" @click="isRegister = false">
← 返回
</el-link>
</el-form-item>
</el-form>
<!-- 登录表单 -->
<el-form ref="form" size="large" autocomplete="off" v-else :model="registerData" :rules="rules">
<el-form-item>
<h1>登录</h1>
</el-form-item>
<el-form-item prop="username">
<el-input :prefix-icon="User" placeholder="请输入用户名" v-model="registerData.username"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input name="password" :prefix-icon="Lock" type="password" placeholder="请输入密码" v-model="registerData.password"></el-input>
</el-form-item>
<el-form-item class="flex">
<div class="flex">
<el-checkbox>记住我</el-checkbox>
<el-link type="primary" :underline="false">忘记密码?</el-link>
</div>
</el-form-item>
<!-- 登录按钮 -->
<el-form-item>
<el-button class="button" type="primary" auto-insert-space>登录</el-button>
</el-form-item>
<el-form-item class="flex">
<el-link type="info" :underline="false" @click="isRegister = true">
注册 →
</el-link>
</el-form-item>
</el-form>
</el-col>
</el-row>
</template>
<style lang="scss" scoped>
/* 样式 */
.login-page {
height: 100vh;
background-color: #fff;
.bg {
background: url('@/assets/logo2.png') no-repeat 60% center / 240px auto,
url('@/assets/login_bg.jpg') no-repeat center / cover;
border-radius: 0 20px 20px 0;
}
.form {
display: flex;
flex-direction: column;
justify-content: center;
user-select: none;
.title {
margin: 0 auto;
}
.button {
width: 100%;
}
.flex {
width: 100%;
display: flex;
justify-content: space-between;
}
}
}
</style>