本人在学习和练手中发现router不太方便并且灵活,学习并练习了路由栈的用法,一共两种方法,一个是修改代码本身,一个是增加配置文件,然后写一下文章保存,以免以后忘记,同时也是想和大家分享一下子,如果对你有帮助,那就再好不过了,这篇文章没有和router的相关介绍,如果想看可以私信我。

 一、什么是路由栈?

  • 此模块是给没学过但是想学的读者们看的。

鸿蒙(HarmonyOS)中的路由栈(Router Stack)是用于管理应用内页面跳转和导航历史的核心机制。其通过栈式数据结构(先进后出)记录页面切换顺序,确保页面状态的保存与恢复,并支持前进、后退等导航操作。                                                       ——来自DeepSeek

  •  想要理解这段话也简单,拿一个瓶子,往里面塞东西,观察你塞进去和取出来的规律,越早放入的东西越晚取出来,路由栈也是同理,每使用push方法跳转一次,往栈中压入一个页面,使用pop()返回上一个页面,讲栈顶的页面删除,跳转到下一个页面。跳转时可以携带相关参数对下一个页面进行操作。

二、路由栈的基本知识

  1. 路由栈的跳转方式
    1. pushUrl: 新页面压入栈顶,保留当前页面状态,可以通过NavDestination的返回按钮或者pop()方法返回上一页。
    2. replaceUrl: 新页面替代当前页面,销毁原页面,无法返回。
  2. 路由栈接口
    1. push相关接口:保留当前页面状态,将新页面压入页面栈。
    2. replace相关接口:新页面替代当前页面,销毁原页面。
    3. remove相关接口:删除页面栈中指定的页面。
    4. pop相关接口:返回上一个界面或者从路由栈中一直返回直到指定值。
    5. move相关接口:移动指定的页面到栈顶。
    6. clear:清空路由栈。
    7. get相关接口:获取路由栈的相关信息。
    8. size:获取栈大小。

以上接口可以参考官方文档:

文档中心https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-basic-components-navigation-V5#navpathstack10

三、使用方法一(纯代码)

  • 一个项目必定有一个启动页面,在启动页面中写入
  @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

即可在代码中跳转页面。


        以上便是路由栈的相关内容,如果有啥需要补充的也可以补充一下,主打一起进步,感谢大家阅读,不打扰的话可以给个点赞关注吗,后续也会更新许多文章。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐