鸿蒙ArkTS布局完全指南-Tabs容器入门
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 + text,tabBar() 还支持传入 @Builder 函数实现完全自定义:
TabContent() { /* ... */ }
.tabBar(this.myCustomTabBuilder)
适用于红点角标、动态数字提醒等场景。
5.4 性能优化建议
- 复杂页面抽取为独立
@Component子组件 - 在
onChange或onAppear中触发网络请求 - 跨 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 模型。
更多推荐




所有评论(0)