HarmonyOS ArkUI 实战:打造高复用性的个人中心页面

在移动应用开发中,“个人中心(Profile Page)” 是最能体现 UI
框架工程化能力的复杂界面之一。它不仅包含顶部的用户信息展示,还涉及大量重复的列表项(如订单、功能菜单)以及滚动交互。

今天,我们将通过解析一个完整的 ArkUI 个人中心代码,带你深入理解如何利用 @Builder 装饰器 实现组件复用、如何通过
@State 管理用户状态,以及如何优雅地组织复杂页面的逻辑。

完整效果
在这里插入图片描述

核心功能与界面概览

我们最终实现的界面包含以下几个核心模块:

  1. 头部区域(Header):显示用户头像、昵称、VIP等级,并提供登录/退出按钮。
  2. VIP 卡片(VIPCard):展示会员特权,引导用户升级。
  3. 功能菜单(MenuSection):这是最核心的复用部分,包含了“我的订单”、“常用功能”、“账户安全”等多个分组,每个分组内包含多个带有图标、标题和角标的列表项。

整个界面布局清晰,通过 Scroll 容器实现了长列表滚动,通过 @Builder 将重复的 UI 逻辑抽象成了独立的构建块。

代码深度解析

我们将代码拆解为四个关键部分进行讲解:状态定义组件化构建数据渲染布局结构

1. 状态管理:@State 装饰器

代码顶部定义了五个状态变量,用于驱动界面的动态变化:

@State isLoggedIn: boolean = true
@State username: string = '晚霞的不甘'
@State avatar: string = '👤'
@State phone: string = '138****8888'
@State vipLevel: number = 3

在这里插入图片描述

  • isLoggedIn:布尔值,控制头部是显示“登录/退出”按钮,还是直接展示用户信息。
  • username, phone, vipLevel:用户的基本信息,当这些数据变化时,界面会自动刷新。
2. 组件化开发:@Builder 装饰器

这是本篇代码最精彩的部分。ArkUI 提供了 @Builder 装饰器,允许我们将一段 UI 构建逻辑封装成一个可复用的“构建器”。这比传统的函数组件更轻量,且可以直接在 build 方法中调用。

头部组件 HeaderSection

该组件根据 isLoggedIn 状态,使用了 if-else 条件渲染:

  • 已登录:显示头像、用户名、电话、VIP 星级(通过 ForEach 循环渲染星星数量)以及“退出”按钮。
  • 未登录:显示“点击登录”提示和“登录”按钮。
// ... 省略部分样式代码
if (this.isLoggedIn) {
    Text(this.username) // 显示用户名
    // ... 其他信息
    ForEach(Array.from({ length: this.vipLevel }), (item: Object, index: number) => {
        Text('⭐') // 根据 vipLevel 数量循环渲染星星
    })
} else {
    Text('点击登录') // 显示登录提示
}

VIP 卡片组件 VIPCard

这是一个独立的卡片,包含标题、描述和一个“立即升级”按钮。

// ... 省略部分样式代码
Row({ space: 16 }) {
    Column({ space: 4 }) {
        Text('VIP 会员')
        Text('尊享特权,升级更多福利')
    }
    .layoutWeight(1)

    Button('立即升级')
}

通用菜单组件 MenuSection

这是复用性最强的部分。它接收两个参数:title(分组标题)和 items(列表项数据数组)。

  • 参数化:通过 title: stringitems: MenuItem[],让同一个组件能渲染不同的内容。
  • 条件渲染标题:如果 title 为空字符串,则不显示标题栏。
  • 数据驱动列表:使用 ForEach(items, ...) 遍历传入的数据数组,动态生成列表项。
  • 角标处理:在列表项内部,通过 if (item.badge !== undefined) 判断是否显示红色的角标(如“5”、“10”)。
@Builder
MenuSection(title: string, items: MenuItem[]) {
    Column({ space: 0 }) {
        // 1. 渲染标题(如果存在)
        if (title !== '') { ... }

        // 2. 渲染列表项
        Column() {
            ForEach(items, (item: MenuItem, index: number) => {
                Row({ space: 12 }) {
                    Text(item.icon)
                    Text(item.title)
                    // 渲染角标
                    if (item.badge !== undefined) {
                        Text(item.badge)
                            .backgroundColor('#FF3B30') // 红色背景
                    }
                    Text('>') // 箭头
                }
                // ... 列表项样式
            })
        }
    }
}
3. 数据结构与列表渲染

代码顶部定义了一个 MenuItem 接口,用于规范列表项的数据格式:

interface MenuItem {
  icon: string    // 图标(如 '📦')
  title: string   // 标题(如 '全部订单')
  badge?: string  // 角标(可选,如 '5')
}

build 方法中,我们直接将数据数组传递给 MenuSection

this.MenuSection('我的订单', [
    { icon: '📦', title: '全部订单', badge: '5' },
    { icon: '💳', title: '待付款', badge: '2' },
    // ... 其他订单项
])

这种方式实现了 “数据与视图分离”,修改数据即可改变界面,无需改动 UI 代码。

4. 布局与滚动容器

整个页面的最外层是一个 Column,内部结构如下:

  • 头部:直接调用 this.HeaderSection()
  • 滚动区域:使用 Scroll() 容器包裹了中间的 Column
    • 作用:当内容高度超出屏幕时,Scroll 容器会自动启用滚动功能,这是实现长页面的标准做法。
    • 属性.layoutWeight(1) 确保滚动区域占据了剩余的全部空间。
  • 背景色:通过 .backgroundColor('#F5F5F5') 设置了滚动区域的背景色,与白色卡片形成对比。

总结与最佳实践

通过这个个人中心页面的实战,我们可以总结出 ArkUI 开发的几个最佳实践:

  1. 善用 @Builder 抽象组件:对于重复出现的 UI 结构(如列表项、卡片、头部),使用 @Builder 封装,可以极大减少代码冗余,提高可维护性。
  2. 数据驱动 UI:定义清晰的接口(如 MenuItem),通过 ForEach 遍历数据来生成 UI,而不是手写大量的重复代码。
  3. 合理使用容器Column 负责垂直排列,Row 负责水平排列,Scroll 负责长内容滚动。理解它们的特性是布局的基础。
  4. 状态管理:使用 @State 管理组件内部状态,利用条件渲染(if-else)实现界面的动态切换。

掌握这些技巧,你就能轻松应对 HarmonyOS 应用开发中绝大多数复杂的页面需求。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐