Tabs 容器入门:鸿蒙 ArkTS 布局完全指南

目标 API:HarmonyOS NEXT 24 | 语言:ArkTS | 框架:ArkUI


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

一、引言

Tabs 容器是 ArkUI 最基础、最常用的导航组件,承载着应用内页面切换的核心职责。从微信的底部导航到淘宝的分类切换,Tab 导航已是移动应用的视觉标配。在鸿蒙生态中,这一切通过 Tabs + TabBar + TabContent 三个组件的组合即可优雅实现。

本文围绕一个完整的可运行示例,拆解 Tabs 容器的布局原理、API 用法与最佳实践。


二、核心概念

2.1 组件关系

Tabs(容器)
  ├── TabContent → 页面 A 的内容
  │     └── .tabBar({ icon, text })  ← 定义标签 A
  ├── TabContent → 页面 B 的内容
  │     └── .tabBar({ icon, text })  ← 定义标签 B
  └── TabContent → 页面 C 的内容
        └── .tabBar({ icon, text })  ← 定义标签 C
组件 角色 说明
Tabs 容器 管理切换逻辑、动画、位置
TabBar 配置属性 附加在 TabContent 上的 .tabBar() 方法
TabContent 内容载体 每个标签页的 UI 内容,必须是 Tabs 直接子节点

TabBar 不是独立组件,而是通过 TabContent.tabBar() 配置的,这一点与 Vue 的 el-tabs 不同。

2.2 适用场景

  • 应用首页底部导航
  • 设置页面的分类切换
  • 数据看板维度切换
  • 任何「点击切换 + 内容联动」的交互场景

三、代码逐段解析

3.1 组件入口与状态定义

import { promptAction } from '@kit.ArkUI'; // Toast 提示(仅辅助用)

@Entry
@Component
struct Index {
  @State currentIndex: number = 0;
  private tabsController: TabsController = new TabsController();

  build() { /* ... */ }
}
  • @Entry:页面入口装饰器
  • @Component:声明 UI 组件
  • @State currentIndex:响应式变量,驱动 UI 更新
  • TabsController:提供 changeIndex() 等编程接口

3.2 声明 Tabs 容器

Tabs({
  barPosition: BarPosition.End,   // 标签栏在底部
  controller: this.tabsController
}) { /* TabContent × 3 */ }
barPosition 选型
vertical=false(默认) vertical=true
BarPosition.Start 顶部 左侧
BarPosition.End 底部 右侧

API 24 统一使用 Start/End 语义,移除了旧版的 Bottom/Top

3.3 标签页一:首页

TabContent() {
  Column() {
    Image($r('sys.media.ohos_app_icon'))
      .width(80).height(80).margin({ top: 40, bottom: 16 })
    Text('欢迎来到首页').fontSize(20).fontColor('#FF1A73E8')
    Row() {
      this.buildFeatureCard('📦', '功能一', '示例描述')
      this.buildFeatureCard('⚙️', '功能二', '示例描述')
    }
    .justifyContent(FlexAlign.SpaceEvenly).width('100%')
    Button('切换到「设置」页')
      .onClick(() => { this.tabsController.changeIndex(2); })
  }
}
.tabBar({
  icon: this.currentIndex === 0 ? '●' : '○',  // 状态驱动图标
  text: '首页'
})

亮点:使用 $r('sys.media.ohos_app_icon') 引用系统内置图标;changeIndex(2) 演示编程式跳转;条件图标利用 @State 响应式更新。

3.4 标签页二:消息

TabContent() {
  Column() {
    Text('消息中心').fontSize(18).fontWeight(FontWeight.Bold)
    ForEach([1, 2, 3], (item: number) => {
      this.buildMessageItem(
        item === 1 ? '🔔' : (item === 2 ? '💬' : '📢'),
        item === 1 ? '系统通知' : (item === 2 ? '好友消息' : '公告'),
        item === 1 ? '刚刚' : (item === 2 ? '10分钟前' : '1小时前')
      )
    }, (item: number) => item.toString())
  }
}
.tabBar({ icon: '💬', text: '消息' })

关注点ForEach 是 ArkTS 列表渲染指令,需提供数据源生成函数键值函数三个参数。

3.5 标签页三:设置

TabContent() {
  Column() {
    Text('应用设置').fontSize(18).fontWeight(FontWeight.Bold)
    this.buildSettingRow('🌙', '深色模式')
    this.buildSettingRow('🔔', '消息通知')
    this.buildSettingRow('🔒', '隐私设置')
    this.buildSettingRow('ℹ️', '关于应用')
  }
}
.tabBar({ icon: '⚙️', text: '设置' })

3.6 属性链式配置

.vertical(false)              // 水平标签栏(默认)
.scrollable(true)             // 允许滑动切换
.barMode(BarMode.Fixed)       // 固定宽度均分
.barWidth('100%')
.barHeight(56)
.animationDuration(300)       // 切换动画 300ms
.width('100%')
.layoutWeight(1)
.onChange((index: number) => {
  this.currentIndex = index;
  // 更新状态,驱动首页图标变化
})
属性 说明
vertical false 水平标签栏(true=垂直)
scrollable true 支持滑动切换
barMode Fixed 所有标签等宽;Scrollable=按内容宽度
animationDuration 300 切换动画时长(ms)
onChange 回调 切换时触发,返回当前索引

四、@Builder 自定义构建函数

@Builder 是 ArkTS 用于抽取复用 UI 片段的装饰器。

4.1 buildFeatureCard —— 功能卡片

@Builder
buildFeatureCard(icon: string, title: string, desc: string) {
  Column() {
    Text(icon).fontSize(32)
    Text(title).fontSize(16)
    Text(desc).fontSize(12).fontColor('#FF999999')
  }
  .padding(16)
  .backgroundColor(Color.White)
  .borderRadius(12)
  .shadow({ radius: 4, color: 'rgba(0,0,0,0.08)', offsetY: 2 })
  .width(130).height(120)
  .justifyContent(FlexAlign.Center)
}

API 24 的 shadow() 支持 ShadowOptions 对象,提供像素级控制。

4.2 buildMessageItem —— 消息条目

@Builder
buildMessageItem(icon: string, title: string, desc: string, time: string) {
  Row() {
    Text(icon).fontSize(28).margin({ right: 12 })
    Column() {
      Text(title).fontSize(16)
      Text(desc).fontSize(13).fontColor('#FF999999')
    }.layoutWeight(1)                   // 占满剩余空间
    Text(time).fontSize(12).fontColor('#FFCCCCCC')
  }
  .width('100%').padding({ left: 16, right: 16, top: 12, bottom: 12 })
  .backgroundColor(Color.White).borderRadius(8)
}

4.3 buildSettingRow —— 设置行

@Builder
buildSettingRow(icon: string, title: string) {
  Row() {
    Text(icon).fontSize(22).margin({ right: 12 })
    Text(title).fontSize(16).layoutWeight(1)
    Text('›').fontSize(20).fontColor('#FFCCCCCC')  // 右箭头符号
  }
  .width('100%').padding({ left: 16, right: 16, top: 14, bottom: 14 })
  .backgroundColor(Color.White).borderRadius(8)
}

右侧 字符比箭头图片更轻量,是设置页面的经典视觉符号。


五、进阶技巧

5.1 Tab 图标状态驱动

.tabBar({
  icon: this.currentIndex === 0 ? '●' : '○',
  text: '首页'
})

利用 @State 的响应式特性使图标随选中状态变化,零额外开销。

5.2 TabContent 懒加载特性

TabContent 默认懒加载:首次选中时才创建内部 UI。这意味着首屏只加载首页,启动速度快。切换回已访问页面时 UI 状态保留。

5.3 自定义 TabBar 样式

除了 icon + texttabBar() 还支持传入 @Builder 函数实现完全自定义:

TabContent() { /* ... */ }
  .tabBar(this.myCustomTabBuilder)

适用于红点角标、动态数字提醒等场景。

5.4 性能优化建议

  • 复杂页面抽取为独立 @Component 子组件
  • onChangeonAppear 中触发网络请求
  • 跨 Tab 共享数据放在父组件 @State@Provide

六、API 24 关键变化

6.1 BarPosition 统一

API 23(6.x) API 24(7.x)
BarPosition.Bottom BarPosition.End
BarPosition.Top BarPosition.Start

6.2 Kit 化导入

// API 23
import { promptAction } from '@ohos.arkui.uiExtension';
// API 24
import { promptAction } from '@kit.ArkUI';

6.3 阴影 API

.shadow({
  radius: 4,
  color: 'rgba(0, 0, 0, 0.08)',
  offsetX: 0,
  offsetY: 2
})

七、常见问题

问题 原因 解决
BarPosition.End 编译报错 API 版本 < 24 检查 targetSdkVersion
TabContent 不显示 缺少宽高 设置 .width('100%').height('100%')
滑动切换失效 scrollable(false) 设置 .scrollable(true)
图标不居中 barWidth 过小 使用 barWidth('100%') + Fixed 模式

八、总结

本文从零构建了一个完整的 Tabs 容器示例,涵盖的核心知识点:

知识点 重要度
Tabs + TabContent 基本结构 ⭐ 必须掌握
barPosition + BarPosition.Start/End ⭐ 必须掌握
TabsController 编程式跳转 ⭐ 必须掌握
.tabBar() 配置图标与文字 ⭐ 必须掌握
@Builder 自定义构建函数 ⭐ 推荐掌握
vertical / scrollable / barMode 🔷 进阶掌握
阴影、动画等视觉增强 🔷 进阶掌握

Tabs 容器是 ArkUI 中学习成本最低、回报最高的组件之一。掌握它,你就掌握了构建鸿蒙应用导航骨架的核心能力。在此基础上可以进一步学习 Navigation 组件,构建更复杂的页面路由架构。

完整源码见 entry/src/main/ets/pages/Index.ets,可直接复制到 DevEco Studio 中编译运行。

环境要求:DevEco Studio 5.2+、HarmonyOS SDK API 24、Stage 模型。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐