Ver código fonte

♻️ refactor(register): 重构注册表单验证逻辑

- 引入zod进行表单验证,替换react-hook-form内置验证规则
- 将RegisterFormData接口迁移到register.schema.ts中通过zod生成
- 新增用户名只能包含字母、数字和下划线的验证规则
- 优化邮箱验证逻辑,支持可选输入但输入时需符合格式要求
- 统一管理所有表单验证规则,提高可维护性和一致性
yourname 4 meses atrás
pai
commit
c39b18c1bd
2 arquivos alterados com 29 adições e 39 exclusões
  1. 3 39
      mini/src/pages/register/index.tsx
  2. 26 0
      mini/src/schemas/register.schema.ts

+ 3 - 39
mini/src/pages/register/index.tsx

@@ -1,6 +1,7 @@
 import { View, Text } from '@tarojs/components'
 import { useEffect, useState } from 'react'
 import { useForm } from 'react-hook-form'
+import { zodResolver } from '@hookform/resolvers/zod'
 import Taro from '@tarojs/taro'
 import { useAuth } from '@/utils/auth'
 import { cn } from '@/utils/cn'
@@ -8,19 +9,14 @@ import { Button } from '@/components/ui/button'
 import { Input } from '@/components/ui/input'
 import { Form, FormField, FormItem, FormLabel, FormControl, FormMessage } from '@/components/ui/form'
 import Navbar from '@/components/ui/navbar'
+import { registerSchema, type RegisterFormData } from '@/schemas/register.schema'
 import './index.css'
 
-interface RegisterFormData {
-  username: string
-  email?: string
-  password: string
-  confirmPassword: string
-}
-
 export default function Register() {
   const { register, isLoading } = useAuth()
   
   const form = useForm<RegisterFormData>({
+    resolver: zodResolver(registerSchema),
     defaultValues: {
       username: '',
       email: '',
@@ -104,17 +100,6 @@ export default function Register() {
               <FormField
                 control={form.control}
                 name="username"
-                rules={{
-                  required: "请输入用户名",
-                  minLength: {
-                    value: 3,
-                    message: "用户名至少3个字符"
-                  },
-                  maxLength: {
-                    value: 20,
-                    message: "用户名最多20个字符"
-                  }
-                }}
                 render={({ field }) => (
                   <FormItem>
                     <FormLabel>用户名</FormLabel>
@@ -137,12 +122,6 @@ export default function Register() {
               <FormField
                 control={form.control}
                 name="email"
-                rules={{
-                  pattern: {
-                    value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
-                    message: "请输入有效的邮箱地址"
-                  }
-                }}
                 render={({ field }) => (
                   <FormItem>
                     <FormLabel>邮箱(可选)</FormLabel>
@@ -166,17 +145,6 @@ export default function Register() {
               <FormField
                 control={form.control}
                 name="password"
-                rules={{
-                  required: "请输入密码",
-                  minLength: {
-                    value: 6,
-                    message: "密码至少6位"
-                  },
-                  maxLength: {
-                    value: 20,
-                    message: "密码最多20位"
-                  }
-                }}
                 render={({ field }) => (
                   <FormItem>
                     <FormLabel>密码</FormLabel>
@@ -202,10 +170,6 @@ export default function Register() {
               <FormField
                 control={form.control}
                 name="confirmPassword"
-                rules={{
-                  required: "请再次输入密码",
-                  validate: (value) => value === form.getValues("password") || "两次输入的密码不一致"
-                }}
                 render={({ field }) => (
                   <FormItem>
                     <FormLabel>确认密码</FormLabel>

+ 26 - 0
mini/src/schemas/register.schema.ts

@@ -0,0 +1,26 @@
+import { z } from 'zod'
+
+export const registerSchema = z.object({
+  username: z.string()
+    .min(3, '用户名至少3个字符')
+    .max(20, '用户名最多20个字符')
+    .regex(/^[a-zA-Z0-9_]+$/, '用户名只能包含字母、数字和下划线'),
+  
+  email: z.string()
+    .optional()
+    .refine(
+      (val) => !val || /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(val),
+      '请输入有效的邮箱地址'
+    ),
+  
+  password: z.string()
+    .min(6, '密码至少6位')
+    .max(20, '密码最多20位'),
+  
+  confirmPassword: z.string()
+}).refine((data) => data.password === data.confirmPassword, {
+  message: '两次输入的密码不一致',
+  path: ['confirmPassword']
+})
+
+export type RegisterFormData = z.infer<typeof registerSchema>