登录注册页:表单校验&自定义规则
表单校验是登录注册页面的安全防线。Element Plus 的 el-form 提供了强大的校验系统,支持必填校验、格式校验、长度校验,以及自定义校验函数。本节重点讲解自定义校验规则的编写方式,以及密码确认、用户名格式等常见场景的实现。
Element Plus 校验系统
校验规则的完整类型定义:
interface FormItemRule {
required?: boolean
message?: string
trigger?: 'blur' | 'change'
min?: number
max?: number
len?: number
pattern?: RegExp
validator?: (rule: any, value: any, callback: any) => void
// ...更多属性
}
typescript
基础校验规则
const formRules: FormRules = {
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 3, max: 20, message: '用户名长度为 3-20 个字符', trigger: 'blur' },
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 6, max: 20, message: '密码长度为 6-20 个字符', trigger: 'blur' },
],
}
typescript
自定义校验函数
密码强度校验
const validatePassword = (_rule: any, value: string, callback: Function) => {
if (!value) {
callback(new Error('请输入密码'))
} else if (value.length < 6) {
callback(new Error('密码长度不能少于 6 个字符'))
} else if (!/[A-Z]/.test(value)) {
callback(new Error('密码必须包含至少一个大写字母'))
} else if (!/[0-9]/.test(value)) {
callback(new Error('密码必须包含至少一个数字'))
} else {
callback()
}
}
typescript
确认密码校验
const validateConfirmPassword = (
_rule: any,
value: string,
callback: Function
) => {
if (!value) {
callback(new Error('请再次输入密码'))
} else if (value !== formData.password) {
callback(new Error('两次输入的密码不一致'))
} else {
callback()
}
}
typescript
使用自定义校验函数:
const formRules: FormRules = {
password: [
{ required: true, validator: validatePassword, trigger: 'blur' },
],
confirmPassword: [
{ required: true, validator: validateConfirmPassword, trigger: 'blur' },
],
}
typescript
邮箱格式校验
const validateEmail = (_rule: any, value: string, callback: Function) => {
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
if (!value) {
callback(new Error('请输入邮箱'))
} else if (!emailRegex.test(value)) {
callback(new Error('邮箱格式不正确'))
} else {
callback()
}
}
typescript
用户名格式校验
const validateUsername = (_rule: any, value: string, callback: Function) => {
const usernameRegex = /^[a-zA-Z0-9_]+$/
if (!value) {
callback(new Error('请输入用户名'))
} else if (!usernameRegex.test(value)) {
callback(new Error('用户名只能包含字母、数字和下划线'))
} else {
callback()
}
}
typescript
异步校验
检查用户名是否已被注册:
const validateUsernameUnique = async (
_rule: any,
value: string,
callback: Function
) => {
if (!value) {
callback(new Error('请输入用户名'))
return
}
try {
const exists = await checkUsernameExists(value)
if (exists) {
callback(new Error('用户名已被注册'))
} else {
callback()
}
} catch {
callback() // 网络错误时不阻止提交
}
}
typescript
表单提交的完整校验流程
const handleSubmit = async () => {
try {
// validate() 返回 Promise,全部通过时 resolve,否则 reject
await formRef.value?.validate()
} catch {
// 校验失败,Element Plus 自动显示错误提示
return
}
loading.value = true
try {
await emit('submit', {
username: formData.username,
password: formData.password,
remember: formData.remember,
})
} finally {
loading.value = false
}
}
typescript
重置表单
在登录/注册切换时,需要清除校验状态和表单数据:
const resetForm = () => {
formRef.value?.resetFields()
}
typescript
resetFields 会同时清除表单值和校验状态,恢复到初始值。
校验时机选择
| trigger 值 | 触发时机 | 适用场景 |
|---|---|---|
blur | 输入框失焦时 | 用户名、密码等需要完整输入的字段 |
change | 值变化时 | 复选框、下拉选择等即时反馈的字段 |
['blur', 'change'] | 两种都触发 | 需要即时反馈又需要完整校验的字段 |
本节小结
- 自定义校验:通过
validator函数实现复杂校验逻辑,调用callback()表示通过,callback(new Error(msg))表示失败。 - 密码确认:在 validator 中对比两个字段的值,确保一致性。
- 异步校验:在 validator 中调用 API 检查唯一性,使用 try/catch 处理网络错误。
- 重置表单:
resetFields()同时清除值和校验状态,适用于表单切换场景。 - 校验时机:
blur用于文本输入,change用于选择类控件。
↑