鸿蒙原生开发手记:徒步迹 - 登录注册页面与表单校验

发布时间:2026/7/17 0:37:28
鸿蒙原生开发手记:徒步迹 - 登录注册页面与表单校验 鸿蒙原生开发手记徒步迹 - 登录注册页面与表单校验实现完整的用户认证流程包含表单验证和交互反馈一、前言登录注册是绝大多数 App 的入口功能。本文实现“徒步迹“的登录注册页面包含手机号输入、密码输入、表单校验、Loading 状态等完整交互。二、登录页面实现2.1 布局设计登录页分为三个区域标题区品牌问候语表单区手机号、密码输入操作区登录按钮、注册入口2.2 完整代码Entry Component struct LoginPage { State private phone: string ; State private password: string ; State private showPassword: boolean false; State private isLoading: boolean false; State private errorMsg: string ; build() { Column() { // 1. 标题区 Column() { Text(欢迎回来) .fontSize(28) .fontWeight(FontWeight.Bold) .fontColor($r(app.color.text_primary)) .width(100%); Text(登录徒步迹开始你的徒步之旅) .fontSize(15) .fontColor($r(app.color.text_secondary)) .width(100%) .margin({ top: 8 }); } .width(100%) .padding({ top: 60, bottom: 40 }) .alignItems(HorizontalAlign.Start); // 2. 表单区 // 手机号 TextInput({ placeholder: 请输入手机号, text: this.phone }) .width(100%) .height(50) .backgroundColor($r(app.color.background_color)) .borderRadius(12) .padding({ left: 16 }) .type(InputType.PhoneNumber) .maxLength(11) .onChange((value: string) { this.phone value; this.errorMsg ; }); // 密码带显示/隐藏切换 Row() { TextInput({ placeholder: 请输入密码, text: this.password }) .layoutWeight(1) .backgroundColor(Color.Transparent) .type(this.showPassword ? InputType.Normal : InputType.Password) .onChange((value: string) { this.password value; this.errorMsg ; }); // 密码可见切换 Text(this.showPassword ? : ️) .fontSize(20) .margin({ right: 16 }) .onClick(() { this.showPassword !this.showPassword; }); } .width(100%).height(50) .backgroundColor($r(app.color.background_color)) .borderRadius(12) .margin({ top: 16 }); // 错误提示 if (this.errorMsg) { Text(this.errorMsg) .fontSize(13) .fontColor($r(app.color.error_color)) .width(100%) .margin({ top: 8 }); } // 忘记密码 Text(忘记密码) .fontSize(14) .fontColor($r(app.color.primary_color)) .width(100%) .textAlign(TextAlign.End) .margin({ top: 12 }); // 3. 登录按钮 Button() { if (this.isLoading) { LoadingProgress().width(24).height(24).color(Color.White); } else { Text(登录).fontSize(16).fontColor(Color.White); } } .width(100%).height(50) .backgroundColor($r(app.color.primary_color)) .borderRadius(25) .margin({ top: 32 }) .enabled(this.isFormValid() !this.isLoading) .onClick(() this.handleLogin()); // 注册入口 Row() { Text(还没有账号).fontSize(14).fontColor(#999); Text(立即注册) .fontSize(14) .fontColor($r(app.color.primary_color)) .onClick(() { router.pushUrl({ url: pages/RegisterPage }); }); } .margin({ top: 24 }) .justifyContent(FlexAlign.Center); } .width(100%).height(100%) .padding({ left: 24, right: 24 }) .backgroundColor(Color.White); } // 表单校验 isFormValid(): boolean { return this.phone.length 11 this.password.length 6; } // 登录逻辑 handleLogin(): void { // 前端校验 if (!/^1[3-9]\d{9}$/.test(this.phone)) { this.errorMsg 请输入正确的手机号; return; } if (this.password.length 6) { this.errorMsg 密码至少6位; return; } this.isLoading true; // 模拟登录请求 setTimeout(() { this.isLoading false; // 登录成功保存 token AppStorage.setOrCreate(isLogged, true); router.replaceUrl({ url: pages/HomePage }); }, 1500); } }三、表单校验最佳实践3.1 手机号格式校验function validatePhone(phone: string): boolean { return /^1[3-9]\d{9}$/.test(phone); } function validatePassword(password: string): { valid: boolean; msg: string } { if (password.length 6) { return { valid: false, msg: 密码至少6位 }; } if (!/[A-Za-z]/.test(password)) { return { valid: false, msg: 密码需包含字母 }; } if (!/\d/.test(password)) { return { valid: false, msg: 密码需包含数字 }; } return { valid: true, msg: }; }3.2 实时校验使用 Watch 监听输入变化实时校验Component struct FormField { State Watch(validate) value: string ; State error: string ; Prop label: string ; Prop rules: ((v: string) string | null)[] []; validate(): void { for (let rule of this.rules) { const err rule(this.value); if (err) { this.error err; return; } } this.error ; } build() { Column() { TextInput({ placeholder: 请输入${this.label}, text: this.value }) .onChange((v) { this.value v; }); if (this.error) { Text(this.error).fontSize(12).fontColor(#F44336); } } } }四、用户体验优化4.1 Loading 状态登录按钮在请求中禁用并显示加载动画Button() { if (this.isLoading) { LoadingProgress().width(24).height(24).color(Color.White); } else { Text(登录).fontSize(16).fontColor(Color.White); } } .enabled(!this.isLoading this.isFormValid())4.2 键盘处理// 点击空白区域收起键盘 Column() .onClick(() { inputMethod.getController()?.stopInputSession(); })4.3 验证码倒计时State countdown: number 0; startCountdown(): void { this.countdown 60; const interval setInterval(() { this.countdown--; if (this.countdown 0) { clearInterval(interval); } }, 1000); }五、数据流说明用户输入 ↓ 表单校验 ← Watch 实时监听 ↓ 通过 调用 API ↓ 保存 Token → AppStorage ↓ 更新登录状态 → Provide(isLogged) ↓ 路由跳转 → HomePage六、总结登录注册页面是 App 的基础功能。本文实现了一个包含完整校验和交互反馈的登录页表单校验、Loading 状态、密码可见切换等交互都能直接用于“徒步迹“ App。下一篇文章将实现验证码登录和忘记密码功能。下一篇预告鸿蒙原生开发手记徒步迹 - 验证码登录与忘记密码