鸿蒙实现自定义路由栈跳转从0到使用
此模块是给没学过但是想学的读者们看的。鸿蒙(HarmonyOS)中的路由栈(Router Stack)是用于管理应用内页面跳转和导航历史的核心机制。其通过栈式数据结构(先进后出)记录页面切换顺序,确保页面状态的保存与恢复,并支持前进、后退等导航操作。——来自DeepSeek想要理解这段话也简单,拿一个瓶子,往里面塞东西,观察你塞进去和取出来的规律,越早放入的东西越晚取出来,路由栈也是同理,每使用p
本人在学习和练手中发现router不太方便并且灵活,学习并练习了路由栈的用法,一共两种方法,一个是修改代码本身,一个是增加配置文件,然后写一下文章保存,以免以后忘记,同时也是想和大家分享一下子,如果对你有帮助,那就再好不过了,这篇文章没有和router的相关介绍,如果想看可以私信我。
一、什么是路由栈?
- 此模块是给没学过但是想学的读者们看的。
鸿蒙(HarmonyOS)中的路由栈(Router Stack)是用于管理应用内页面跳转和导航历史的核心机制。其通过栈式数据结构(先进后出)记录页面切换顺序,确保页面状态的保存与恢复,并支持前进、后退等导航操作。 ——来自DeepSeek
- 想要理解这段话也简单,拿一个瓶子,往里面塞东西,观察你塞进去和取出来的规律,越早放入的东西越晚取出来,路由栈也是同理,每使用push方法跳转一次,往栈中压入一个页面,使用pop()返回上一个页面,讲栈顶的页面删除,跳转到下一个页面。跳转时可以携带相关参数对下一个页面进行操作。
二、路由栈的基本知识
- 路由栈的跳转方式
- pushUrl: 新页面压入栈顶,保留当前页面状态,可以通过NavDestination的返回按钮或者pop()方法返回上一页。
- replaceUrl: 新页面替代当前页面,销毁原页面,无法返回。
- 路由栈接口
- push相关接口:保留当前页面状态,将新页面压入页面栈。
- replace相关接口:新页面替代当前页面,销毁原页面。
- remove相关接口:删除页面栈中指定的页面。
- pop相关接口:返回上一个界面或者从路由栈中一直返回直到指定值。
- move相关接口:移动指定的页面到栈顶。
- clear:清空路由栈。
- get相关接口:获取路由栈的相关信息。
- size:获取栈大小。
以上接口可以参考官方文档:
三、使用方法一(纯代码)
- 一个项目必定有一个启动页面,在启动页面中写入
@Provide('myPageStack') pageStack: NavPathStack = new NavPathStack()
这句话的意思是新建一个路由栈,并且由@Provide进行跨页面(组件)传递,在子组件或后代组件双向同步,使用@Consume获取。如下:
@Consume('myPageStack') pageStack: NavPathStack
以上两个装饰器不认识的读者可以参考下方官方文档学习:
在启动页面中,还需要将根组件修改成Navigation,并传入路由栈,如下:
Navigation(this.pageStack) {}
在此基础上,还需要新增一个函数,例如:
import { MyOtherPage} from 'login/src/main/ets/pages/MyOtherPage'
@Builder
myRouter(name: string, param: object) {
if(name === 'myOtherPage') {
MyOtherPage()
}
}
然后向Navigation组件添加该函数,具体效果如下:
Navigation(this.pageStack) {
}
.navDestination(this.myRouter)
至此,就可以在Navigation包裹的范围内进行路由栈跳转,使用示例:
import { MyOtherPage } from './MyOtherPage'
@Entry
@Component
struct Index {
@Provide('myPageStack') pageStack: NavPathStack = new NavPathStack()
@Builder
myRouter(name: string, param: string) {
if(name === 'MyOtherPage') {
MyOtherPage()
}
}
build() {
Navigation(this.pageStack) {
Column() {
Button('点击跳转')
.onClick(() => {
this.pageStack.pushPathByName('MyOtherPage', null)
})
}
}
.navDestination(this.myRouter)
}
}
如果想要携带参数,可以使用下列代码:
import { MyOtherPage } from './MyOtherPage'
export interface StackMessageType {
message: string
}
@Entry
@Component
struct Index {
@Provide('myPageStack') pageStack: NavPathStack = new NavPathStack()
@Builder
myRouter(name: string, param: object) {
if(name === 'MyOtherPage') {
MyOtherPage({
data: param as StackMessageType
})
}
}
build() {
Navigation(this.pageStack) {
Column() {
Button('点击跳转')
.onClick(() => {
this.pageStack.pushPathByName('MyOtherPage', { message: '这里是Index界面' } as StackMessageType)
})
}
}
.navDestination(this.myRouter)
}
}
经过上述操作,即可在下一页面中接收到数据,如下:
import { StackMessageType } from "./IndexPage"
@Component
export struct MyOtherPage {
@Prop data: StackMessageType | undefined = undefined
build() {
NavDestination() {
Column() {
Text('这里是MyOtherPage页面')
Text(`从上一个页面传下来的数据为: ${JSON.stringify(this.data)}`)
}
.width('100%')
.height('100%')
}
}
}
注意:跳转后的页面必须被NavDestination包裹,不然的话,会没有任何东西,一片白。
效果如下:
四、使用方法二(配置文件)
- 在如图所示位置新增router_map.json文件。

- 添加成功后写入代码:
{
"routerMap": [
{
"name": "DetailedPage", // 自定义名字,根据这个名字进行跳转
"pageSourceFile": "src/main/ets/pages/DetailedPage.ets", // 文件位置,可以输入src/后进行快捷输入
"buildFunction": "DetailedPageBuilder" // 页面构建器,用@Builder修饰的函数
}
]
}
- 在同模块的module.json5文件中新增代码,与"name"节点同级。:
"routerMap": "$profile:router_map",
- 之后与上方一直,在根页面中增加代码如上方使用方法一一致,如下:
import { MyOtherPage } from './MyOtherPage'
@Entry
@Component
struct Index {
@Provide('myPageStack') pageStack: NavPathStack = new NavPathStack()
build() {
Navigation(this.pageStack) {
Column() {
Button('点击跳转')
.onClick(() => {
this.pageStack.pushPathByName('MyOtherPage', null)
})
}
}
}
}
- 测试应该可以通过,不想测试了,大概是可以跳转的,子页面中更改为:
import { StackMessageType } from "./IndexPage"
@Builder
export function MyOtherPageBuilder(name: string, params: object) {
MyOtherPage()
}
@Component
export struct MyOtherPage {
build() {
NavDestination() {
Column() {
Text('这里是MyOtherPage页面')
}
.width('100%')
.height('100%')
}
}
}
- 在后代页面中只需要使用NavDestination组件作为根组件,使用
@Consume('myPageStack') pageStack: NavPathStack
即可在代码中跳转页面。
以上便是路由栈的相关内容,如果有啥需要补充的也可以补充一下,主打一起进步,感谢大家阅读,不打扰的话可以给个点赞关注吗,后续也会更新许多文章。
更多推荐



所有评论(0)