页面路由
HarmonyOS 提供两种页面路由方案:
| 方案 | 版本 | 适用场景 |
|---|---|---|
Navigation + NavPathStack | API 10+ | 官方推荐,支持复杂导航、转场动画 |
@ohos.router | API 9+ | 简单页面跳转,已不推荐新项目使用 |
Navigation 方案(推荐)
创建新页面
typescript
// entry/src/main/ets/pages/DetailPage.ets
@Component
export struct DetailPage {
@Prop id: string = ''
@Prop title: string = ''
build() {
Column() {
Text(`详情页`)
.fontSize(24)
.fontWeight(FontWeight.Bold)
.margin(20)
Text(`ID: ${this.id}`)
.fontSize(16)
.margin(10)
Text(`标题: ${this.title}`)
.fontSize(16)
.margin(10)
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
入口页配置 Navigation
typescript
// entry/src/main/ets/pages/Index.ets
import { DetailPage } from './DetailPage'
@Entry
@Component
struct Index {
// 创建导航栈
pathStack: NavPathStack = new NavPathStack()
// 页面映射表
@Builder
pageMap(name: string) {
if (name === 'detail') {
DetailPage()
}
}
build() {
Navigation(this.pathStack) {
Column({ space: 20 }) {
Text('首页')
.fontSize(24)
.fontWeight(FontWeight.Bold)
Button('打开详情页(带参数)')
.onClick(() => {
this.pathStack.pushPath({
name: 'detail',
params: {
id: '42',
title: '示例标题'
}
})
})
Button('打开详情页(无参数)')
.onClick(() => {
this.pathStack.pushPath({ name: 'detail' })
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
.navDestination(this.pageMap)
.mode(NavigationMode.Stack)
.hideTitleBar(false)
.title('我的应用')
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
在详情页获取参数
typescript
@Component
export struct DetailPage {
@State id: string = ''
@State title: string = ''
aboutToAppear() {
// 通过 NavDestination 获取参数
const params = this.getUIContext().getRouter().getParams() as Record<string, string>
if (params) {
this.id = params['id'] || ''
this.title = params['title'] || ''
}
}
build() {
Column() {
// ...
Button('返回')
.onClick(() => {
// 返回上一页
this.getUIContext().getRouter().back()
})
}
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
导航栈操作
typescript
// 跳转到新页面
this.pathStack.pushPath({ name: 'detail', params: {} })
// 返回上一页
this.pathStack.pop()
// 返回到指定页面
this.pathStack.popToName('home')
// 清空栈并跳转
this.pathStack.clear()
this.pathStack.pushPath({ name: 'login' })
// 替换当前页面
this.pathStack.replacePath({ name: 'newPage' })
// 获取栈深度
const depth = this.pathStack.size()
// 获取当前页面参数
const params = this.pathStack.getParamByIndex(0)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@ohos.router 方案(旧)
注意
此方案已不推荐新项目使用,仅作了解。
配置路由表
json
// resources/base/profile/main_pages.json
{
"src": [
"pages/Index",
"pages/DetailPage"
]
}1
2
3
4
5
6
7
2
3
4
5
6
7
页面跳转
typescript
import router from '@ohos.router'
// 跳转页面
router.pushUrl({
url: 'pages/DetailPage',
params: { id: '42' }
})
// 返回
router.back()
// 获取参数
const params = router.getParams() as Record<string, string>1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
页面传参对比
| 方式 | Navigation | @ohos.router |
|---|---|---|
| 路由表配置 | 代码中 navDestination | main_pages.json |
| 传参 | params 对象 | params 对象 |
| 取参 | getUIContext().getRouter().getParams() | router.getParams() |
| 返回 | back() | back() |
| 栈操作 | 丰富(pop/popToName/clear) | 简单 |
完整示例:带底部导航的应用
typescript
@Entry
@Component
struct MainPage {
@State currentIndex: number = 0
pathStack: NavPathStack = new NavPathStack()
@Builder
tabBuilder(title: string, index: number, selectedIcon: Resource, normalIcon: Resource) {
Column() {
Image(this.currentIndex === index ? selectedIcon : normalIcon)
.width(24)
.height(24)
Text(title)
.fontSize(12)
.fontColor(this.currentIndex === index ? '#007DFF' : '#999999')
}
.onClick(() => {
this.currentIndex = index
})
}
build() {
Navigation(this.pathStack) {
Tabs({ barPosition: BarPosition.End }) {
TabContent() {
HomeTab()
}
.tabBar(this.tabBuilder('首页', 0, $r('app.media.home_selected'), $r('app.media.home')))
TabContent() {
DiscoverTab()
}
.tabBar(this.tabBuilder('发现', 1, $r('app.media.discover_selected'), $r('app.media.discover')))
TabContent() {
ProfileTab()
}
.tabBar(this.tabBuilder('我的', 2, $r('app.media.profile_selected'), $r('app.media.profile')))
}
}
.hideTitleBar(true)
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43