鸿蒙系统app开发:运动监测app(五)
State装饰器实现UI与数据的双向绑定username和password实时响应用户输入isLoading控制异步操作期间的UI状态rememberMe保存用户偏好设置。
页面设计
登陆界面
1 页面结构与布局设计
1.1 整体布局架构
@Entry
@Component
struct Login {
@State username: string = ''
@State password: string = ''
@State isLoading: boolean = false
@State rememberMe: boolean = false
private userManager: UserManager = UserManager.getInstance();
build() {
Column() {
// 头部标题区域
Column({ space: 10 }) {
Text('运动监测')
.fontSize(32)
.fontWeight(FontWeight.Bold)
.fontColor('#007DFF')
Text('欢迎回来,请登录您的账户')
.fontSize(16)
.fontColor('#666666')
}
.margin({ top: 80, bottom: 60 })
.width('100%')
.alignItems(HorizontalAlign.Center)
采用Column垂直布局作为根容器,头部区域使用嵌套Column实现标题和副标题组合,通过margin控制页面间距,top:80确保内容不被状态栏遮挡,用HorizontalAlign.Center实现水平居中布局。
1.2 表单区域设计
// 登录表单区域
Column({ space: 20 }) {
// 用户名输入框
Column({ space: 8 }) {
Text('用户名')
.fontSize(14)
.fontColor('#333333')
.width('100%')
TextInput({ placeholder: '请输入用户名', text: this.username })
.width('100%')
.height(50)
.fontSize(16)
.backgroundColor('#F8F9FA')
.borderRadius(8)
.padding({ left: 15, right: 15 })
.onChange((value: string) => {
this.username = value;
})
}
.width('100%')
// 密码输入框
Column({ space: 8 }) {
Text('密码')
.fontSize(14)
.fontColor('#333333')
.width('100%')
TextInput({ placeholder: '请输入密码', text: this.password })
.width('100%')
.height(50)
.fontSize(16)
.type(InputType.Password)
.backgroundColor('#F8F9FA')
.borderRadius(8)
.padding({ left: 15, right: 15 })
.onChange((value: string) => {
this.password = value;
})
}
.width('100%')
表单设计:
表单容器使用space:20统一控制内部元素间距
每个输入项采用Column嵌套,label和input分离
TextInput设置固定高度50,确保触控区域充足
圆角8px和背景色#F8F9FA
2 状态管理与数据流
2.1 响应式状态定义
@State username: string = ''
@State password: string = ''
@State isLoading: boolean = false
@State rememberMe: boolean = false
private userManager: UserManager = UserManager.getInstance();
状态管理:
@State装饰器实现UI与数据的双向绑定
username和password实时响应用户输入
isLoading控制异步操作期间的UI状态
rememberMe保存用户偏好设置
2.2 状态驱动的UI更新
// 记住我选项
Row() {
Checkbox()
.select(this.rememberMe)
.onChange((value: boolean) => {
this.rememberMe = value;
})
Text('记住我')
.fontSize(14)
.fontColor('#666666')
.margin({ left: 8 })
}
.width('100%')
.margin({ top: 10 })
// 登录按钮
Button('登录')
.width('100%')
.height(50)
.fontSize(18)
.fontColor('#FFFFFF')
.backgroundColor('#007DFF')
.borderRadius(25)
.enabled(!this.isLoading && this.username.length > 0 && this.password.length > 0)
.onClick(() => {
this.handleLogin();
})
.margin({ top: 20 )
// 加载状态
if (this.isLoading) {
LoadingProgress()
.width(30)
.height(30)
.color('#007DFF')
.margin({ top: 10 })
}
状态绑定机制:
Checkbox通过select绑定rememberMe状态
按钮enabled属性与多个状态条件关联
条件渲染只在isLoading为true时显示加载指示器
3 用户交互与业务逻辑
3.1 登录业务流程
// 处理登录
private async handleLogin(): Promise<void> {
if (this.username.trim().length === 0 || this.password.trim().length === 0) {
this.showToast('请输入用户名和密码');
return;
}
this.isLoading = true;
try {
const success = this.userManager.login(this.username, this.password);
if (success) {
this.showToast('登录成功');
// 登录成功后跳转到主页
setTimeout(() => {
router.replaceUrl({
url: 'pages/Index'
});
}, 500);
} else {
this.showToast('用户名或密码错误');
}
} catch (error) {
console.error('登录过程出错:', error);
this.showToast('登录失败,请重试');
} finally {
this.isLoading = false;
}
}
业务逻辑分层:
输入验证层:检查用户名密码非空
认证逻辑层:调用UserManager进行身份验证
结果处理层:根据认证结果执行不同分支
异常处理层:捕获并处理可能的错误
3.2 用户反馈机制
// 安全的 toast 显示方法
private showToast(message: string): void {
try {
promptAction.showToast({
message: message,
duration: 2000
});
} catch (error) {
console.error('显示 toast 失败:', error);
}
}
反馈设计特点:
使用鸿蒙原生promptAction模块
统一的2秒显示时长
try-catch包装确保稳定性
多种场景的提示文案设计
4 路由导航与页面生命周期
4.1 页面导航实现
// 注册链接
Row() {
Text('还没有账户?')
.fontSize(14)
.fontColor('#666666')
Text('立即注册')
.fontSize(14)
.fontColor('#007DFF')
.fontWeight(FontWeight.Medium)
.margin({ left: 5 })
.onClick(() => {
router.pushUrl({
url: 'pages/Register'
});
})
}
.margin({ top: 30 )
// 忘记密码
Text('忘记密码?')
.fontSize(14)
.fontColor('#007DFF')
.margin({ top: 20 )
.onClick(() => {
router.pushUrl({
url: 'pages/ForgotPassword'
});
})
4.2 页面生命周期管理
onPageShow(): void {
console.log('Login页面显示');
// 检查是否已登录
const currentUser = this.userManager.getCurrentUser();
if (currentUser) {
console.log('检测到已登录用户,自动跳转到主页');
router.replaceUrl({
url: 'pages/Index'
});
}
}
生命周期:
onPageShow钩子在页面显示时触发
自动检查用户登录状态
使用replaceUrl避免返回登录页
5 样式系统与视觉设计
5.1 色彩系统设计
.width('100%')
.height('100%')
.padding(20)
.backgroundColor('#FFFFFF')
.alignItems(HorizontalAlign.Center)
5.2 布局与间距系统
页面边距:20px
组件间距:20px(表单区域)
内部间距:8px(输入项内部)
特殊间距:80px(顶部),60px(头部底部)
组件尺寸:
按钮高度:50px
输入框高度:50px
加载指示器:30x30px
按钮圆角:25px
6 性能优化
6.1 条件渲染
// 加载状态
if (this.isLoading) {
LoadingProgress()
.width(30)
.height(30)
.color('#007DFF')
.margin({ top: 10 })
}
性能优化:
条件渲染
状态驱动的UI更新
6.2 错误边界处理
} catch (error) {
console.error('登录过程出错:', error);
this.showToast('登录失败,请重试');
} finally {
this.isLoading = false;
}
用try-catch-finally确保资源释放
更多推荐




所有评论(0)