一、HarmonyOS Next -- Navigation的跳转方式

此文章仅供学习,不作其他用途。
如有侵权,请联系删除。
欢迎批评指正!!! 谢谢!!!

Navigation

Navigation组件是路由导航的根视图容器,一般情况下作为根容器使用。

一、 使用配置文件进行页面跳转

1. 创建一个根页面视图 NavPathStackDemo.ets

代码如下:

@Entry
@Preview
@Component
struct NavPathStackDemo {
  pageInfos: NavPathStack = new NavPathStack();
  build() {
    Navigation(this.pageInfos) {
      Column() {
        Button('pushPath')
          .width('80%')
          .height(40)
          .margin(20)
          .onClick(() => {
            this.pageInfos.pushPath({ name: 'pageOne' })
          })
      }
    }
  }
}

注意

  • @Entry装饰器修饰的页面,需要在 main_pages.json文件中引用,否则会报错。
  • @Preview装饰器是可以在模拟器中预览该页面。可以不写。
  • @Component装饰器是标配,不说了。

2. 写子页面PageOne.ets

代码如下:

@Builder
export function PageOneBuilder(name: string, param: object) {
  PageOne();
}

@Component
struct PageOne {
  pageInfos: NavPathStack = new NavPathStack();
  build() {
    NavDestination() {
      Column() {
        Button('pushPathByName', { stateEffect: true, type: ButtonType.Capsule })
          .width('80%')
          .height(40)
          .margin(20)
      }
    }
    .title('PageOne')
  }
}

PageOneBuilder函数是需要注意的。使用@Builder装饰器。别忘了 export关键字

3. 配置文件

在路径 src/main/resources/base/profile 文件夹下,配置 route_map.json文件,代码如下:

{
  "routerMap": [
    {
      "name": "pageOne",
      "pageSourceFile": "src/main/ets/view/PageOne.ets",
      "buildFunction": "PageOneBuilder",
      "data": {
        "description": "this is pageOne"
      }
    }
  ]
}

注意:

  • name: 对应的就是 跳转页面时写的 this.pageInfos.pushPath({ name: 'pageOne' })
  • pageSourceFile: 对应的是需要跳转的页面的路径
  • buildFunction: 对应的是 子页面中 使用 @Builder修饰的函数(创建子页面对象)
  • 'data': 可写可不写

4. 在工程文件中配置route_map.json文件

找到 工程配置文件 module.json5文件, 在 module里边配置 routerMap属性,如下所示:

{
  "module": {
    ...
    "routerMap": "$profile:route_map"
  }
}

接下来,就可以运行程序,测试Navigation的跳转效果了。

5. onReady的使用

场景:如果在PageOne页面中,继续跳转下一个页面PageTwo
PageTwo.ets代码如下:

@Builder
export function PageTwoBuilder(name: string) {
  PageTwo();
}

@Component
export struct PageTwo {
  pathStack: NavPathStack = new NavPathStack();
  build() {
    NavDestination() {
      Column() {
        Text('Page Two')
        Button('Go To Page Three!', {type: ButtonType.Capsule})
          .onClick(() => {
            this.pathStack.pushPath({ name: 'pageThree'})
          })
      }
    }
  }
}

route_map.json文件中配置如下:

{
      "name": "pageTwo",
      "pageSourceFile": "src/main/ets/view/PageTwo.ets",
      "buildFunction": "PageTwoBuilder"
    },

运行程序,当点击 PageOne页面中的pushPathByName按钮跳转PageTwo页面时,会没有反应,无法进行跳转。这时就需要用到onReady
先来看一下官方解释:

onReady

onReady回调函数中有一个 NavDestinationContext参数,可以通过这个参数拿到当前NavDestination所处的页面栈。
PageOne.ets中代码如下(部分代码已省略):

@Builder
export function PageOneBuilder(name: string, param: object) {
  PageOne();
}

@Component
struct PageOne {
  pageInfos: NavPathStack = new NavPathStack();
  build() {
    NavDestination() {
      Column() {
        Button('pushPathByName', { stateEffect: true, type: ButtonType.Capsule })
          .width('80%')
          .height(40)
          .margin(20)
          .onClick(() => {
            this.pageInfos.pushPathByName("pageTwo", null);
          })
      }
    }
    .title('PageOne')
    .onReady((context: NavDestinationContext) => {
      this.pageInfos = context.pathStack;
    })
  }
}

再次运行程序,点击pushPathByName按钮,可以看到跳转到PageTwo页面了。

PageTwo页面

二、 使用navDestination属性

1. 创建主页面NavPathStackDemoTwo.ets文件

代码如下:

import { MinePage } from '../view/MinePage';

@Entry
@Preview
@Component
struct NavPathStackDemoTwo {
  @Provide('pathStack') pageInfos: NavPathStack = new NavPathStack();
  @Builder
  PageTo(name: string) {
    if (name === 'mine_page') {
      MinePage();
    }
  }

  build() {
    Navigation(this.pageInfos) {
      Column() {
        Button('Go to mine page!')
          .width('80%')
          .height(40)
          .margin(20)
          .onClick(() => {
            this.pageInfos.pushPath({ name: 'mine_page' })
          })
      }
    }
    .navDestination(this.PageTo)
  }
}

注意:navPathStack变量使用的是 @Provide('xxx)修饰
@Provide(xxx)修饰的变量:会将该变量也就是navPathStack传递给跳转后的后代组件
而后代组件在获取时,需要使用@Consume来修饰,后边会有代码体现并讲解@Consume

navDestination(builder: (name: string, param: unknown) => void): NavigationAttribute;

Set builder for user-defined NavDestination component.
翻译之后:用户自定义 NavDestination 组件的集合构造器
需要传入一个自定义的集合构造器 builder,也就是上边代码中使用 @Builder修饰的PageTo, 可以看到需要传入一个name的形参,param不是必传
注意: 这里的name 就是通过 this.pageInfos.pushPath({ name: 'mine_page' }) 中的name参数传入,
PageTo内部通过对name值的匹配来控制需要做的事情。

2. 创建后代组件MinePage.ets

代码如下:

@Component
export struct MinePage {
  @Consume pathStack: NavPathStack;
  build() {
    NavDestination() {
      Column() {
        Text('Mine Page')
        Button('跳转到设置页面')
          .onClick(() => {
            this.pathStack.pushPathByName('settingPage', null);
          })
      }
      .width('100%')
      .height('100%')
      .backgroundColor('#f1f3f5')
    }
    .title('我的')
    .backgroundColor('#f1f3f5')
  }
}

运行程序,点击按钮,则会跳转到settingPage所指向的SettingPage页面。依然是在route_map.json中配置。
有三点需要注意的地方:

  1. @Consume: 通过@Consume装饰器在后代组件中拿到祖代组件传递过来的路由栈数据。
  2. @Consume pathStack: NavPathStack;: 其中的 pathStack变量命名需要和祖代组件中@Provide(xxx)中的 xxx保持一致的命名。
  3. 这里不再使用onReady去获取当前路由栈信息

SettingPage页面如果还需要跳转到 更下层的页面,依然可以使用@Consume修饰的变量xxx,获取到祖代传递过来的路由栈数据。
SettingPage代码如下:

@Builder
export function SettingPageBuilder() {
  SettingPage();
}

@Entry
@Component
export struct SettingPage {
  @Consume pathStack: NavPathStack;
  build() {
    NavDestination() {
      Column() {
        Text('设置页面---')
        Button('测试', { type: ButtonType.Capsule })
          .onClick(() => {
            this.pathStack.pushPathByName('pageThree', null);
          })
      }
      .width('100%')
      .height('100%')
    }
  }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容