HarmonyOS应用开发实战(基础篇)Day07-《登录注册页面》

设计:从零构建一个专业级登录页面

在移动应用开发中,登录/注册页面 是用户与系统建立身份关联的第一道门户,其设计质量直接影响用户的第一印象与使用体验。本文将基于 ArkTS 与 HarmonyOS 的 ArkUI 框架,从 UI 设计到交互逻辑,完整实现一个简洁、安全、响应式的登录页面。

一、设计目标与视觉规范

根据需求草图,我们的登录页面需包含以下核心元素:

  • 顶部 Logo:品牌标识,增强识别度;
  • 账号输入框:支持文本输入,带占位提示;
  • 密码输入框:密文显示,保障安全;
  • 操作按钮组:包含"登录"与"取消"两个功能按钮;
  • 交互反馈:输入校验、加载状态、跳转逻辑。

整体风格遵循 HarmonyOS 设计语言(HUAWEI Design)

  • 使用 vp 单位确保多设备适配;
  • 布局居中,留白合理;
  • 按钮色彩对比鲜明,操作路径清晰;
  • 提供即时反馈,避免用户困惑。

最终效果如下图所示:


二、页面实现(静态布局)

在未接入业务逻辑前,我们首先构建静态 UI 结构 ,确保视觉呈现符合设计稿。通过 Column 垂直布局 + Row 水平按钮组,配合 spacemarginwidth 等属性,精准控制组件间距与尺寸。

完成后的静态页面如下:

关键点

  • Logo 采用圆形裁剪(borderRadius: 100);
  • 输入框宽度统一为父容器的 80%;
  • 按钮等宽排列,间距 10vp;
  • 整体垂直居中,顶部留出足够呼吸空间。

三、页面实现(动态交互)

静态页面只是骨架,真正的价值在于交互逻辑。我们为登录页添加以下功能:

  • 用户输入实时绑定;
  • 点击"取消"清空表单;
  • 点击"登录"校验凭据;
  • 校验成功则跳转主页;
  • 加载状态防止重复提交;
  • 错误提示引导用户修正。

最终交互效果如下动图所示:


四、整体代码解析(深度剖析)

以下是对完整代码的逐层拆解与优化建议,涵盖模块导入、数据建模、状态管理、UI 渲染、事件处理、路由跳转六大核心环节。

ts 复制代码
import { promptAction, router, Router } from '@kit.ArkUI';

// 定义用户接口
interface User {
  uname: string;
  upwd: string;
}

@Entry
@Component
struct Index {
  // 1. 定义状态变量,绑定输入框的值
  @State user: User = { uname: '', upwd: '' };
  // 2. 定义加载状态,防止重复点击
  @State isLoading: boolean = false;

  build() {
    Column({ space: 10 }) {
      // Logo
      Image($r('app.media.my'))
        .width(200)
        .height(200)
        .margin({ top: 50, bottom: 20 })
        .border({ radius: 100 });

      // 账户名
      TextInput({
        placeholder: '请输入账户名',
        text: this.user.uname
      })
        .type(InputType.Normal)
        .width('80%')
        .onChange((value) => {
          this.user.uname = value;
        });

      // 密码
      TextInput({
        placeholder: '请输入密码',
        text: this.user.upwd
      })
        .type(InputType.Password)
        .width('80%')
        .onChange((value) => {
          this.user.upwd = value;
        });

      // 按钮行
      Row({ space: 10 }) {
        Button(this.isLoading ? '登录中...' : '登录')
          .width('50%')
          .onClick(() => this.handleLogin())
          .enabled(!this.isLoading);

        Button('取消')
          .width('50%')
          .backgroundColor('#ff433e3e')
          .onClick(() => this.handleCancel());
      }
      .width('80%')
      .justifyContent(FlexAlign.Center);
    }
    .width('100%')
    .height('100%')
    .alignItems(HorizontalAlign.Center);
  }

  handleCancel() {
    this.user.uname = '';
    this.user.upwd = '';
    AlertDialog.show({ message: JSON.stringify(this.user) });
    promptAction.showToast({ message: '已取消登录', duration: 2000 });
  }

  handleLogin() {
    if (this.user.uname === 'admin' && this.user.upwd === '123456') {
      router.pushUrl({
        url: 'pages/IndexPage'
      }).then(() => {
        console.log('跳转到主页成功');
      });
    } else {
      promptAction.showToast({ message: '登录成功', duration: 2000 }); // ⚠️ 文案错误
    }
  }
}

(一)模块导入:明确依赖边界

ts 复制代码
import { promptAction, router, Router } from '@kit.ArkUI';
  • promptAction:提供轻量级用户反馈(如 Toast),不打断当前操作流;
  • router :页面路由核心 API,支持 pushUrl(入栈)、replaceUrl(替换)、back(返回);
  • 问题Router 是类型定义,实际未使用,可移除以减少包体积;
  • 缺失项 :代码中使用了 InputTypeAlertDialog,但未导入,会导致编译失败。应补充:
ts 复制代码
import { 
  promptAction, 
  router, 
  InputType, 
  AlertDialog 
} from '@kit.ArkUI';

📌 工程规范:所有使用的 API 必须显式导入,避免隐式依赖。


(二)数据建模:用接口约束结构

ts 复制代码
interface User {
  uname: string;
  upwd: string;
}
  • 使用 TypeScript 接口定义数据契约,提升代码可读性与类型安全性;
  • 字段命名建议采用语义化词汇(如 username / password),但若项目已有约定,可保持一致;
  • 在大型项目中,可将此类接口抽离至 types.ts 文件,实现跨组件复用。

(三)状态管理:@State 驱动 UI 更新

ts 复制代码
@State user: User = { uname: '', upwd: '' };
@State isLoading: boolean = false;
  • @State 是 ArkTS 的核心状态装饰器,任何被其修饰的变量,当值发生变化时,会自动触发组件重新渲染
  • user 对象用于双向绑定输入框,实现"输入 → 状态 → UI 同步";
  • isLoading 控制按钮的交互状态,是防重复提交的关键机制。

💡 响应式原理:ArkUI 内部通过依赖收集机制,仅更新受影响的子树,性能高效。


(四)UI 布局:语义化与可维护性

  • 使用 $r('app.media.my') 引用资源,确保多分辨率适配;
  • border({ radius: 100 }) 将正方形图变为圆形,符合头像设计惯例;
  • 注意 :需确保 resources/base/media/my.png 存在,否则显示空白。
2. 输入框
  • text: this.user.xxx 实现单向数据流(状态 → UI);
  • onChange 实现反向同步(UI → 状态),构成双向绑定;
  • 密码框使用 InputType.Password 自动启用掩码,无需手动处理。
3. 按钮组
  • Row({ space: 10 }) 简洁实现等分布局;
  • 登录按钮文字动态切换,提升用户体验;
  • enabled(!this.isLoading) 禁用按钮,防止多次点击导致多次请求。

(五)交互逻辑:健壮性与用户体验

1. 取消逻辑(handleCancel)
  • 清空状态变量,自动同步到输入框;
  • 使用 AlertDialog 调试当前状态(开发阶段可用,上线应移除);
  • promptAction.showToast 提供非阻塞提示,符合移动端 UX 规范。
2. 登录逻辑(handleLogin)------需重点优化!

当前代码存在三大问题:

❌ 问题 1:提示文案错误
ts 复制代码
else {
  promptAction.showToast({ message: '登录成功', duration: 2000 });
}

应改为

ts 复制代码
promptAction.showToast({ message: '账号或密码错误', duration: 2000 });
❌ 问题 2:缺少加载状态控制

点击登录后,isLoading 从未设为 true,导致按钮无法显示"登录中..."。

❌ 问题 3:无异常处理

router.pushUrl 可能因页面路径错误而失败,应捕获异常。

优化后代码

ts 复制代码
async handleLogin() {
  if (!this.user.uname || !this.user.upwd) {
    promptAction.showToast({ message: '请输入完整信息', duration: 2000 });
    return;
  }

  this.isLoading = true; // 开启加载状态

  try {
    if (this.user.uname === 'admin' && this.user.upwd === '123456') {
      await router.pushUrl({ url: 'pages/IndexPage' });
      console.log('跳转到主页成功');
    } else {
      promptAction.showToast({ message: '账号或密码错误', duration: 2000 });
    }
  } catch (err) {
    console.error('路由跳转失败:', err);
    promptAction.showToast({ message: '系统错误,请重试', duration: 2000 });
  } finally {
    this.isLoading = false; // 无论成功失败,重置状态
  }
}

🔒 安全建议

  • 真实项目中,切勿硬编码账号密码
  • 应调用后端接口进行认证,使用 HTTPS 传输;
  • 密码字段不应明文存储于前端状态。

(六)路由配置:确保跳转路径有效

ts 复制代码
url: 'pages/IndexPage'
  • 该路径必须在 main_pages.json(或 module.json5)中注册:
json 复制代码
{
  "src": ["pages/IndexPage.ets"],
  "name": "IndexPage"
}
  • 否则 router.pushUrl 会失败,且无明显报错。

五、总结与延伸

本案例虽小,却涵盖了 ArkTS 开发的核心范式:

能力 技术点
UI 构建 Column/Row 布局、Image/TextInput/Button 组件
状态管理 @State 装饰器、双向绑定
用户交互 onClickonChange 事件处理
系统集成 promptAction 提示、router 路由
工程规范 接口定义、模块导入、错误处理

后续可扩展方向:

  1. 表单校验增强:添加正则验证(如邮箱格式);
  2. 记住密码 :结合 @StorageLink 持久化本地缓存;
  3. 验证码登录:集成短信/图形验证码;
  4. 主题适配 :支持深色模式(@Watch 监听系统主题);
  5. 国际化 :使用 $r('app.string.login_title') 替代硬编码文本。

通过这样一个"小而全"的登录页,开发者不仅能掌握 ArkTS 基础语法,更能建立起组件化、状态驱动、用户体验优先的现代应用开发思维。

相关推荐
三雷科技2 小时前
人工智能系统学习知识点:游戏辅助工具开发
人工智能·学习·游戏
我命由我123452 小时前
Photoshop - Photoshop 工具栏(63)注释工具
学习·ui·职场和发展·求职招聘·职场发展·学习方法·photoshop
不爱吃糖的程序媛2 小时前
Flutter性能监控插件鸿蒙适配实战指南
flutter·harmonyos
『往事』&白驹过隙;2 小时前
在ARM开发中 volatile与const关键字的关键用途
c语言·arm开发·mcu·物联网·学习·iot
无巧不成书02182 小时前
React Native 鸿蒙系统(HarmonyOS/OpenHarmony)适配全景指南
react native·react.js·华为·开源·交互·harmonyos
星空22232 小时前
【HarmonyOS】React Native of HarmonyOS实战:手势组合与协同
react native·华为·harmonyos
星空22232 小时前
【HarmonyOS】React Native of HarmonyOS实战:手势状态管理
react native·华为·harmonyos
平安的平安2 小时前
【OpenHarmony】React Native鸿蒙实战:WebSocket心跳保活
websocket·react native·harmonyos
键盘鼓手苏苏4 小时前
Flutter for OpenHarmony:markdown 纯 Dart 解析引擎(将文本转化为结构化 HTML/UI) 深度解析与鸿蒙适配指南
前端·网络·算法·flutter·ui·html·harmonyos