ArkTS 中 Tabs 组件用法

ArkTS 中 Tabs 组件用法

ArkTS 中 Tabs 组件总结

一、Tabs 组件概述

Tabs 组件是 ArkTS 中用于实现选项卡式导航的容器组件,通常与 TabContent 子组件配合使用,用于构建多页面切换的应用界面。

二、基本用法

2.1 基础语法

Tabs(value?: { barPosition?: BarPosition, index?: number, controller?: TabsController })

2.2 最简单的示例

@Entry
@***ponent
struct BasicTabsExample {
  build() {
    Tabs() {
      TabContent() {
        Text('首页内容')
      }
      .tabBar('首页')

      TabContent() {
        Text('消息内容')
      }
      .tabBar('消息')

      TabContent() {
        Text('我的内容')
      }
      .tabBar('我的')
    }
  }
}

三、构造参数 (TabsOptions)

参数名 类型 必填 说明
barPosition BarPosition TabBar 的位置,默认为 BarPosition.Start
index number 初始选中的标签页索引,默认为 0
controller TabsController Tabs 控制器,用于控制 Tabs 组件的切换

3.1 BarPosition 枚举

enum BarPosition {
  Start, // TabBar 位于顶部或左侧(默认)
  End, // TabBar 位于底部或右侧
}

四、常用属性

4.1 布局相关

vertical

设置 Tabs 是否为垂直布局

Tabs() {
  // ...
}
.vertical(false)  // false: 水平布局(默认), true: 垂直布局
barMode

设置 TabBar 的布局模式

Tabs() {
  // ...
}
.barMode(BarMode.Fixed)  // Fixed: 固定模式, Scrollable: 可滚动模式

BarMode 枚举:

  • BarMode.Fixed:所有标签均分 TabBar 宽度,不可滚动
  • BarMode.Scrollable:TabBar 可滚动,适合标签数量较多的场景
barWidth

设置 TabBar 的宽度

Tabs() {
  // ...
}
.barWidth(200)  // 数字或百分比
barHeight

设置 TabBar 的高度

Tabs() {
  // ...
}
.barHeight(56)  // 常用值: 56vp

4.2 样式相关

scrollable (已废弃,请使用 barMode)

是否可滚动

Tabs() {
  // ...
}
.scrollable(true)
animationDuration

设置切换动画的持续时间(毫秒)

Tabs() {
  // ...
}
.animationDuration(300)  // 默认 300ms
barBackgroundColor

设置 TabBar 的背景颜色

Tabs() {
  // ...
}
.barBackgroundColor('#F1F3F5')

4.3 交互相关

onChange

Tab 页签切换时触发的回调

Tabs() {
  // ...
}
.onChange((index: number) => {
  console.info('当前选中的 Tab 索引: ' + index)
})
onTabBarClick

点击 TabBar 时触发的回调

Tabs() {
  // ...
}
.onTabBarClick((index: number) => {
  console.info('点击了 Tab 索引: ' + index)
})

五、TabsController 控制器

TabsController 用于控制 Tabs 组件的页面切换。

5.1 方法

方法名 参数 说明
changeIndex index: number 切换到指定索引的 Tab

5.2 使用示例

@Entry
@***ponent
struct TabsControllerExample {
  private controller: TabsController = new TabsController()
  @State currentIndex: number = 0

  build() {
    Column() {
      // 自定义按钮控制 Tab 切换
      Row({ space: 10 }) {
        Button('切换到首页')
          .onClick(() => {
            this.controller.changeIndex(0)
          })
        Button('切换到消息')
          .onClick(() => {
            this.controller.changeIndex(1)
          })
      }
      .margin({ bottom: 20 })

      Tabs({
        controller: this.controller,
        index: this.currentIndex
      }) {
        TabContent() {
          Text('首页内容')
            .fontSize(20)
        }
        .tabBar('首页')

        TabContent() {
          Text('消息内容')
            .fontSize(20)
        }
        .tabBar('消息')

        TabContent() {
          Text('我的内容')
            .fontSize(20)
        }
        .tabBar('我的')
      }
      .onChange((index: number) => {
        this.currentIndex = index
      })
    }
    .width('100%')
    .height('100%')
    .padding(20)
  }
}

六、TabContent 组件

TabContent 是 Tabs 的子组件,用于定义每个标签页的内容。

6.1 tabBar 属性

tabBar 可以设置为字符串、CustomBuilder 或对象类型。

简单文本
TabContent() {
  Text('内容')
}
.tabBar('标题')
完整对象配置
TabContent() {
  Text('内容')
}
.tabBar({
  icon: $r('app.media.home'),
  selectedIcon: $r('app.media.home_selected'),
  text: '首页'
})
自定义 TabBar
@Builder TabBarBuilder(title: string, icon: Resource, index: number) {
  Column() {
    Image(this.currentIndex === index ? this.selectedIcons[index] : icon)
      .width(24)
      .height(24)
    Text(title)
      .fontSize(12)
      .fontColor(this.currentIndex === index ? '#007DFF' : '#999')
  }
  .width('100%')
  .height('100%')
  .justifyContent(FlexAlign.Center)
}

// 使用自定义 TabBar
TabContent() {
  Text('首页内容')
}
.tabBar(this.TabBarBuilder('首页', $r('app.media.home'), 0))

七、实际应用场景

7.1 底部导航栏

@Entry
@***ponent
struct BottomNavigation {
  @State currentIndex: number = 0
  private tabsController: TabsController = new TabsController()

  @Builder TabBuilder(title: string, targetIndex: number, icon: Resource, selectedIcon: Resource) {
    Column() {
      Image(this.currentIndex === targetIndex ? selectedIcon : icon)
        .size({ width: 24, height: 24 })
      Text(title)
        .fontSize(10)
        .fontColor(this.currentIndex === targetIndex ? '#007DFF' : '#999999')
        .margin({ top: 4 })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
    .onClick(() => {
      this.currentIndex = targetIndex
      this.tabsController.changeIndex(targetIndex)
    })
  }

  build() {
    Tabs({
      barPosition: BarPosition.End,
      controller: this.tabsController,
      index: this.currentIndex
    }) {
      TabContent() {
        Column().width('100%').height('100%').backgroundColor('#00CB87')
      }
      .tabBar(this.TabBuilder('首页', 0, $r('app.media.home'), $r('app.media.home_selected')))

      TabContent() {
        Column().width('100%').height('100%').backgroundColor('#007DFF')
      }
      .tabBar(this.TabBuilder('消息', 1, $r('app.media.message'), $r('app.media.message_selected')))

      TabContent() {
        Column().width('100%').height('100%').backgroundColor('#FFBF00')
      }
      .tabBar(this.TabBuilder('我的', 2, $r('app.media.profile'), $r('app.media.profile_selected')))
    }
    .width('100%')
    .height('100%')
    .barHeight(56)
    .barBackgroundColor(Color.White)
    .animationDuration(300)
    .onChange((index: number) => {
      this.currentIndex = index
    })
  }
}

7.2 顶部选项卡(可滚动)

@Entry
@***ponent
struct ScrollableTopTabs {
  @State currentIndex: number = 0
  private categories: string[] = [
    '推荐', '热点', '科技', '娱乐', '体育',
    '财经', '军事', '汽车', '时尚', '游戏'
  ]

  @Builder TabBarBuilder(title: string, index: number) {
    Column() {
      Text(title)
        .fontSize(16)
        .fontWeight(this.currentIndex === index ? FontWeight.Bold : FontWeight.Normal)
        .fontColor(this.currentIndex === index ? '#007DFF' : '#333333')
        .padding({ left: 16, right: 16 })
    }
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }

  build() {
    Column() {
      Tabs({ index: this.currentIndex }) {
        ForEach(this.categories, (category: string, index: number) => {
          TabContent() {
            Column() {
              Text(`${category} 内容区域`)
                .fontSize(20)
                .margin({ top: 50 })
            }
            .width('100%')
            .height('100%')
            .backgroundColor('#F5F5F5')
          }
          .tabBar(this.TabBarBuilder(category, index))
        })
      }
      .width('100%')
      .height('100%')
      .barMode(BarMode.Scrollable)
      .barHeight(44)
      .barBackgroundColor(Color.White)
      .animationDuration(200)
      .onChange((index: number) => {
        this.currentIndex = index
      })
    }
  }
}

7.3 垂直选项卡

@Entry
@***ponent
struct VerticalTabsExample {
  @State currentIndex: number = 0

  build() {
    Tabs({ index: this.currentIndex }) {
      TabContent() {
        Column() {
          Text('分类1内容')
        }
        .width('100%')
        .height('100%')
        .backgroundColor('#FFE4E1')
      }
      .tabBar('分类1')

      TabContent() {
        Column() {
          Text('分类2内容')
        }
        .width('100%')
        .height('100%')
        .backgroundColor('#E0FFFF')
      }
      .tabBar('分类2')

      TabContent() {
        Column() {
          Text('分类3内容')
        }
        .width('100%')
        .height('100%')
        .backgroundColor('#F0FFF0')
      }
      .tabBar('分类3')
    }
    .width('100%')
    .height('100%')
    .vertical(true)           // 设置为垂直布局
    .barWidth(100)            // TabBar 宽度
    .barMode(BarMode.Fixed)
    .onChange((index: number) => {
      this.currentIndex = index
    })
  }
}

八、常用属性速查表

属性名 类型 默认值 说明
vertical boolean false 是否为垂直布局
barMode BarMode BarMode.Fixed TabBar 布局模式
barWidth Length - TabBar 宽度
barHeight Length - TabBar 高度
animationDuration number 300 切换动画时长(毫秒)
barBackgroundColor ResourceColor - TabBar 背景颜色
barPosition BarPosition BarPosition.Start TabBar 位置
index number 0 当前选中的标签页索引
scrollable boolean false 是否可滚动(已废弃)

九、事件回调

事件名 参数类型 说明
onChange (index: number) Tab 切换完成时触发
onTabBarClick (index: number) 点击 TabBar 时触发

十、最佳实践建议

10.1 性能优化

  1. 使用 barMode 替代废弃的 scrollable 属性
  2. 当标签数量较多时,使用 BarMode.Scrollable 避免挤压
  3. 合理使用 animationDuration,不要设置过长的动画时长

10.2 用户体验

  1. 底部导航建议使用 3-5 个标签页
  2. 顶部选项卡适合内容分类较多的场景
  3. 提供清晰的选中状态视觉反馈
  4. 自定义 TabBar 时保持一致的尺寸和样式

10.3 布局建议

  1. 底部导航:barPosition: BarPosition.End + barHeight: 56
  2. 顶部选项卡:barPosition: BarPosition.Start + barHeight: 44-48
  3. 垂直侧边栏:vertical: true + barWidth: 80-120

10.4 注意事项

  1. TabContent 必须作为 Tabs 的直接子组件
  2. index 值从 0 开始
  3. 使用 TabsController 时需要绑定 controller 参数
  4. 自定义 TabBar 需要使用 @Builder 装饰器

十一、总结

Tabs 组件是 HarmonyOS 应用开发中最常用的导航组件之一,通过合理配置属性和自定义 TabBar,可以实现多样化的导航效果。主要应用场景包括:

  • 底部导航栏:适合主要功能模块切换
  • 顶部选项卡:适合内容分类浏览
  • 侧边导航:适合层级结构展示

掌握 Tabs 组件的使用,可以构建出用户体验良好的多页面应用。


参考文档

  • 华为开发者联盟 - Tabs 组件
转载请说明出处内容投诉
CSS教程网 » ArkTS 中 Tabs 组件用法

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买