fix:注册添加表单校验
This commit is contained in:
parent
4d64dd9178
commit
54aaf421be
@ -7,84 +7,41 @@
|
||||
{{ isRegister ? "加入乐绘世界,开启创作之旅" : "欢迎回来,继续你的创作" }}
|
||||
</p>
|
||||
|
||||
<a-form
|
||||
:model="form"
|
||||
:rules="currentRules"
|
||||
@finish="handleSubmit"
|
||||
layout="vertical"
|
||||
class="auth-form"
|
||||
>
|
||||
<a-form ref="formRef" :model="form" :rules="currentRules" layout="vertical" class="auth-form"
|
||||
@keyup.enter="submitForm">
|
||||
<a-form-item v-if="showNicknameField" name="nickname" label="昵称">
|
||||
<a-input
|
||||
v-model:value="form.nickname"
|
||||
placeholder="给自己取个名字吧"
|
||||
size="large"
|
||||
/>
|
||||
<a-input v-model:value="form.nickname" placeholder="给自己取个名字吧" size="large" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-if="showPhoneField" name="phone" label="手机号">
|
||||
<a-input
|
||||
v-model:value="form.phone"
|
||||
placeholder="请输入手机号"
|
||||
size="large"
|
||||
:maxlength="11"
|
||||
/>
|
||||
<a-input v-model:value="form.phone" placeholder="请输入手机号" size="large" :maxlength="11" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-if="showSmsCodeField" name="smsCode" label="验证码">
|
||||
<div style="display: flex; gap: 8px">
|
||||
<a-input
|
||||
v-model:value="form.smsCode"
|
||||
placeholder="请输入6位验证码"
|
||||
size="large"
|
||||
:maxlength="6"
|
||||
style="flex: 1"
|
||||
/>
|
||||
<a-button
|
||||
size="large"
|
||||
:disabled="smsCountdown > 0 || !isPhoneValid"
|
||||
:loading="smsSending"
|
||||
@click="handleSendSms"
|
||||
style="min-width: 120px"
|
||||
>
|
||||
<a-input v-model:value="form.smsCode" placeholder="请输入6位验证码" size="large" :maxlength="6" style="flex: 1" />
|
||||
<a-button size="large" :disabled="smsCountdown > 0 || !isPhoneValid" :loading="smsSending"
|
||||
@click="handleSendSms" style="min-width: 120px">
|
||||
{{ smsCountdown > 0 ? `${smsCountdown}s 后重发` : "获取验证码" }}
|
||||
</a-button>
|
||||
</div>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-if="showUsernameField" name="username" label="用户名">
|
||||
<a-input
|
||||
v-model:value="form.username"
|
||||
placeholder="请输入用户名"
|
||||
size="large"
|
||||
/>
|
||||
<a-form-item v-if="showUsernameField" name="username" label="账号">
|
||||
<a-input v-model:value="form.username" :maxlength="12" placeholder="请输入账号" size="large" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-if="showPasswordField" name="password" label="密码">
|
||||
<a-input-password
|
||||
v-model:value="form.password"
|
||||
placeholder="请输入密码"
|
||||
size="large"
|
||||
/>
|
||||
<a-input-password v-model:value="form.password" :maxlength="16" placeholder="请输入密码" size="large" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-if="isRegister" name="confirmPassword" label="确认密码">
|
||||
<a-input-password
|
||||
v-model:value="form.confirmPassword"
|
||||
placeholder="再次输入密码"
|
||||
size="large"
|
||||
/>
|
||||
<a-input-password v-model:value="form.confirmPassword" :maxlength="16" placeholder="再次输入密码" size="large" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item>
|
||||
<a-button
|
||||
type="primary"
|
||||
html-type="submit"
|
||||
size="large"
|
||||
:loading="loading"
|
||||
block
|
||||
class="auth-btn"
|
||||
>
|
||||
<a-button type="primary" html-type="button" size="large" :loading="loading" block class="auth-btn"
|
||||
@click="submitForm">
|
||||
{{ isRegister ? "注册并登录" : "登录" }}
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
@ -124,6 +81,7 @@ import { ref, reactive, computed, onUnmounted } from "vue"
|
||||
import { useRouter, useRoute } from "vue-router"
|
||||
import { message } from "ant-design-vue"
|
||||
import { publicAuthApi } from "@/api/public"
|
||||
import type { FormInstance } from "ant-design-vue"
|
||||
import type { Rule } from "ant-design-vue/es/form"
|
||||
|
||||
const router = useRouter()
|
||||
@ -148,7 +106,9 @@ const smsCountdown = ref(0)
|
||||
const smsSending = ref(false)
|
||||
let smsTimer: ReturnType<typeof setInterval> | null = null
|
||||
|
||||
const isPhoneValid = computed(() => /^1[3-9]\d{9}$/.test(form.phone))
|
||||
const formRef = ref<FormInstance>()
|
||||
|
||||
const isPhoneValid = computed(() => /^1[3-9]\d{9}$/.test(form.phone.trim()))
|
||||
|
||||
// 控制字段显示的 computed
|
||||
const showNicknameField = computed(() => isRegister.value)
|
||||
@ -157,15 +117,32 @@ const showSmsCodeField = computed(() => isRegister.value || (!isRegister.value &
|
||||
const showUsernameField = computed(() => isRegister.value || (!isRegister.value && loginMethod.value === 'password'))
|
||||
const showPasswordField = computed(() => isRegister.value || (!isRegister.value && loginMethod.value === 'password'))
|
||||
|
||||
// 基础校验规则
|
||||
// 账号名:仅英文字母与数字
|
||||
const USERNAME_PATTERN = /^[a-zA-Z0-9]+$/
|
||||
// 密码:英文字母、数字、ASCII 可打印特殊字符(不含空格)
|
||||
const PASSWORD_PATTERN = /^[\x21-\x7E]+$/
|
||||
|
||||
// 基础校验规则(与后端 PublicRegisterDto / PublicLoginDto 一致)
|
||||
const baseRules: Record<string, Rule[]> = {
|
||||
username: [
|
||||
{ required: true, message: "请输入用户名", trigger: "blur" },
|
||||
{ min: 4, message: "用户名至少4个字符", trigger: "blur" },
|
||||
{ required: true, message: "请输入账号名", trigger: "blur" },
|
||||
{ min: 4, message: "账号名为4-12个字符", trigger: "blur" },
|
||||
{ max: 12, message: "账号名为4-12个字符", trigger: "blur" },
|
||||
{
|
||||
pattern: USERNAME_PATTERN,
|
||||
message: "账号名只能包含英文字母与数字",
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
password: [
|
||||
{ required: true, message: "请输入密码", trigger: "blur" },
|
||||
{ min: 6, message: "密码至少6个字符", trigger: "blur" },
|
||||
{ min: 6, message: "密码为6-16个字符", trigger: "blur" },
|
||||
{ max: 16, message: "密码为6-16个字符", trigger: "blur" },
|
||||
{
|
||||
pattern: PASSWORD_PATTERN,
|
||||
message: "密码只能包含英文字母、数字与特殊字符",
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
confirmPassword: [
|
||||
{ required: true, message: "请确认密码", trigger: "blur" },
|
||||
@ -181,7 +158,8 @@ const baseRules: Record<string, Rule[]> = {
|
||||
],
|
||||
nickname: [
|
||||
{ required: true, message: "请输入昵称", trigger: "blur" },
|
||||
{ min: 2, message: "昵称至少2个字符", trigger: "blur" },
|
||||
{ min: 2, message: "昵称为2-20个字符", trigger: "blur" },
|
||||
{ max: 20, message: "昵称为2-20个字符", trigger: "blur" },
|
||||
],
|
||||
phone: [
|
||||
{ required: true, message: "请输入手机号", trigger: "blur" },
|
||||
@ -218,6 +196,7 @@ const currentRules = computed(() => {
|
||||
})
|
||||
|
||||
const handleSendSms = async () => {
|
||||
form.phone = form.phone.trim()
|
||||
if (!isPhoneValid.value || smsCountdown.value > 0) return
|
||||
smsSending.value = true
|
||||
try {
|
||||
@ -259,6 +238,25 @@ const switchToLogin = () => {
|
||||
loginMethod.value = 'password'
|
||||
}
|
||||
|
||||
/** 校验前去除各字段前后空格并写回表单,再触发校验 */
|
||||
function trimFormFields() {
|
||||
const t = (v: string) => (typeof v === "string" ? v.trim() : v)
|
||||
form.nickname = t(form.nickname)
|
||||
form.phone = t(form.phone)
|
||||
form.smsCode = t(form.smsCode)
|
||||
form.username = t(form.username)
|
||||
form.password = t(form.password)
|
||||
form.confirmPassword = t(form.confirmPassword)
|
||||
}
|
||||
|
||||
function submitForm() {
|
||||
trimFormFields()
|
||||
formRef.value
|
||||
?.validate()
|
||||
.then(() => handleSubmit())
|
||||
.catch(() => { })
|
||||
}
|
||||
|
||||
const handleSubmit = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user