HarmonyOS 鸿蒙Next中Tabs作导航时,标签页的生命周期是?
HarmonyOS 鸿蒙Next中Tabs作导航时,标签页的生命周期是?
采用的是 API15,使用 Tabs 作底部导航栏时,对应内容在 TabContent 中,那么生命周期是怎么触发的? 我的登录业务将 user 相关信息存到 AppStorage 中了,而在好友分组页面中用 @StorageLink(‘user’) 拿到用户信息,然后在 aboutToAppear 和 onAppear 都试过了调接口获取该用户的好友分组列表,为什么登录后在好友分组页面并没有成功走到 aboutToAppear 或者 onAppear 中的逻辑,生命周期根本就没有触发啊?
// Layout
import { FriendPage } from './FriendPage';
import { HomePage } from './HomePage';
import { Mine } from './Mine';
import { PostPage } from './PostPage';
import { AppStorageV2, Font } from '@kit.ArkUI';
import { User } from '../module/user';
@Builder
export function LayoutBuilder() {
Layout();
}
@Component
struct Layout {
private tabsController: TabsController = new TabsController();
@State currentIndex: number = 0;
pathStack: NavPathStack = AppStorageV2.connect(NavPathStack, 'navStack',() => new NavPathStack())!
font: Font = new Font();
[@StorageLink](/user/StorageLink)('user')
user: User | undefined = AppStorage.get('user')
aboutToAppear(): void {
// 注册字体
this.font.registerFont({
familyName: '阿里汉仪智能黑体',
familySrc: $rawfile('fonts/阿里汉仪智能黑体.ttf')
})
if(!this.user){
this.pathStack.pushPathByName("Login", null, true);
}
}
@Builder
tabBarBuilder(title: string, targetIndex: number, selectedIcon: Resource, unselectIcon: Resource) {
Column({ space: 5 }) {
Image(this.currentIndex === targetIndex ? selectedIcon : unselectIcon)
.width(24)
Text(title)
.fontFamily('阿里汉仪智能黑体')
.fontSize(14)
.fontColor(this.currentIndex === targetIndex ? '#0A59F7' : '#63AAAA')
.textAlign(TextAlign.Center)
.fontWeight(500)
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
.onClick(() => {
this.currentIndex = targetIndex;
this.tabsController.changeIndex(targetIndex)
})
}
build() {
NavDestination() {
Tabs({ barPosition: BarPosition.End, controller: this.tabsController }) {
TabContent() {
HomePage()
}
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
.backgroundColor('#F6F6F6')
.tabBar(this.tabBarBuilder('主页', 0, $r('app.media.home_blue_selected'), $r('app.media.home')))
TabContent() {
PostPage()
}
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
.backgroundColor('#F6F6F6')
.tabBar(this.tabBarBuilder('动态', 1, $r('app.media.post_blue_selected'), $r('app.media.post')))
TabContent() {
FriendPage()
}
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
.backgroundColor('#F6F6F6')
.tabBar(this.tabBarBuilder('好友', 2, $r('app.media.friends_blue_selected'), $r('app.media.friends')))
TabContent() {
Mine()
}
.backgroundColor('#F6F6F6')
.tabBar(this.tabBarBuilder('我的', 3, $r('app.media.mine_blue_selected'), $r('app.media.mine')))
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
}
.divider({
strokeWidth: '2vp',
color: Color.Gray,
})
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
.scrollable(false)
.vertical(false)
}
.onReady((context: NavDestinationContext) => {
this.pathStack = context.pathStack;
})
}
}
// 好友分组页
import { Friend } from "../network/interface/friend";
import { getFriendCategoriesApi } from "../network/api/friend"
import { AppStorageV2, PromptAction } from "@kit.ArkUI"
import { User } from "../module/user";
@Component
export struct FriendPage {
pathStack: NavPathStack = AppStorageV2.connect(NavPathStack, 'navStack', () => new NavPathStack())!
private tabsController: TabsController = new TabsController();
toast: PromptAction = new PromptAction()
@State
categoryList: Friend.ResFriendCategories[] = []
getCategories = async () => {
try {
const res = await getFriendCategoriesApi()
this.categoryList = res.data
console.log('====================好友分组列表:', res.data)
} catch (e) {
this.toast.showToast({
message: '获取好友分组列表失败',
duration: 2000,
})
console.log(e)
}
}
aboutToAppear(): void {
this.getCategories()
}
[@StorageLink](/user/StorageLink)('user')
user: User | undefined = AppStorage.get('user')
build() {
Column({ space: 5 }) {
// 搜索区域
Row() {
Image($r('app.media.ic_search'))
.width(22)
.fillColor('#817D83')
TextInput({ placeholder: '搜索好友...' })
.backgroundColor(Color.Transparent)
.placeholderColor('#817D83')
.padding({ left: 5 })
// 除去别的宽度,剩余的给 TextInput
.layoutWeight(1)
.fontColor('#999')
// Image($r('app.media.ic_code'))
// .width(20)
// .fillColor('#817D83')
}
.backgroundColor('#E9E9E9')
.width('100%')
.border({ radius: 20 })
.padding({ left: 8, right: 8 })
Tabs({ barPosition: BarPosition.Start, controller: this.tabsController }) {
TabContent() {
Text('Tab1')
}
.tabBar(SubTabBarStyle.of('全部好友'))
ForEach(this.categoryList, (item: Friend.ResFriendCategories) => {
TabContent() {
Text("分组id:" + item.pkId)
}
.tabBar(SubTabBarStyle.of(item.name))
}, (item: Friend.ResFriendCategories) => item.pkId.toString())
}
.scrollable(true)
.vertical(false)
}
.width('100%')
.height('100%')
.padding({
left: 10,
right: 10,
top: 5,
bottom: 5
})
}
}
更多关于HarmonyOS 鸿蒙Next中Tabs作导航时,标签页的生命周期是?的实战教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS Next中,Tabs作为导航时,标签页生命周期如下:
- 首次加载时触发aboutToAppear
- 离开当前标签页时触发aboutToDisappear
- 返回标签页时再次触发aboutToAppear
- 组件销毁时触发aboutToDisappear
非当前显示的标签页会被保留在内存中,不会重复创建。页面状态保持由ArkUI框架自动管理,切换标签页不会触发页面重建。
更多关于HarmonyOS 鸿蒙Next中Tabs作导航时,标签页的生命周期是?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS Next中,Tabs组件作为导航时,TabContent的生命周期触发机制如下:
- 首次加载时,默认显示的TabContent会触发aboutToAppear和onAppear生命周期
- 切换Tab时:
- 新显示的TabContent会触发aboutToAppear和onAppear
- 被隐藏的TabContent会触发onDisappear
- 但不会销毁隐藏的TabContent,只是将其移出视图
根据你的代码分析,问题可能出在:
- FriendPage可能不是初始显示的TabContent,所以首次登录时不会触发其生命周期
- 建议在FriendPage中添加onPageShow回调来监听页面显示事件:
onPageShow() {
this.getCategories()
}
- 或者使用Tabs的onChangeIndex事件来主动触发数据加载:
Tabs({
onChangeIndex: (index: number) => {
if(index === 2) { // 好友页的索引
this.getCategories()
}
}
})
- 确保AppStorage中的user数据变更能正确触发@StorageLink的更新
这种设计是为了优化性能,避免不必要的资源消耗。只有当前显示的TabContent会保持活跃状态。