HarmonyOS页面路由 原创

liuyang8888
发布于 2025-3-22 12:13
浏览
0收藏

页面路由指在应用程序中实现不同页面之间的跳转和数据传递。

HarmonyOS提供了Router模块,通过不同的url地址,可以方便地进行页面路由,轻松地访问不同的页面。

包的使用及引用

import router from'@ohos.router'
  • 1.

1.  pushUrl-压栈跳转

pushUrl(options:RouterOptions): Promise<void>
  • 1.

场景: 如果我们从列表页跳转到详情页查看详情,点击返回还要继续查看列表页,可以使用pushUrl,打开详情页的同时,保留了列表页在栈中。

接下来测试一下:

(1)建立两个Page,HmList和HmDetail,如图所示。

HarmonyOS页面路由-鸿蒙开发者社区

(2)实现HmList的布局,代码如下。

class ListItemInfo {
  title: string = ""
  id: number = 0
}

@Entry
@Component
struct HmList {
  @State list: ListItemInfo[]= Array.from(Array(100),(_: number, index:number) => {
    return {
      title: `我是第${index + 1}个`,
      id: index + 1
    } as ListItemInfo
  })
  build() {
    Column({space: 20 }) {
      Row(){
        Text("列表数据")
          .textAlign(TextAlign.Center)
          .width('100%')
          .height(40)
      } .border({
        color: '#f3f4f5',
        width: {
          bottom: 1
        }
      })
      List({space: 10 }) {
        ForEach(this.list, (item: ListItemInfo) => {
          ListItem () {
            Row(){
              Text(item.title)
              Button("查看详情")
                .height(30)
            }.width('100%')
            .justifyContent(FlexAlign.SpaceBetween)
            .padding({
              left: 10,
              right: 10
            })
          }
        })
      }
    }
  }
}
  • 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.


实现效果,如图所示。

HarmonyOS页面路由-鸿蒙开发者社区

(3)实现HmDetail布局,代码如下:

@Entry
@Component
struct HmDetail {

  build() {
    Column(){
      Row(){
        Text("详情页")
          .width('100%')
          .textAlign(TextAlign.Center)
      }.height(40)
      .border({
        color: '#f3f4f5',
        width: {
          bottom: 1
        }
      })

      Column(){
        Text("详情页")
          .fontSize(50)
      }
      .layoutWeight(1)
      .justifyContent(FlexAlign.Center)
    }
    .height('100%')
  }
}
  • 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.


实现效果,如图所示。

HarmonyOS页面路由-鸿蒙开发者社区

(4)在HmList中导入router包,完成路由跳转

import router 
    
from '@ohos.router'
Button("查看详情").onClick(() => {
    router.pushUrl({ url: 'pages/HmDetail' })
})
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

完整代码如下:

import router from '@ohos.router'

class ListItemInfo {
  title: string = ""
  id: number = 0
}

@Entry
@Component
struct HmList {
  @State list: ListItemInfo[]= Array.from(Array(100),(_: number, index:number) => {
    return {
      title: `我是第${index +1}个`,
      id: index + 1
    } as ListItemInfo
  })
  build() {
    Column({space: 20 }) {
      Row(){
        Text("列表数据")
          .textAlign(TextAlign.Center)
          .width('100%')
          .height(40)
      } .border({
        color: '#f3f4f5',
        width: {
          bottom: 1
        }
      })
      List({space: 10 }) {
        ForEach(this.list, (item: ListItemInfo) => {
          ListItem () {
            Row(){
              Text(item.title)
              Button("查看详情").onClick(()=> {
                router.pushUrl({url: 'pages/HmDetail' })
              })
                .height(30)
            }.width('100%')
            .justifyContent(FlexAlign.SpaceBetween)
            .padding({
              left: 10,
              right: 10
            })
          }
        })
      }
    }
  }
}
  • 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.  replaceUrl-替换跳转

有一个登录页(Login)和一个个人中心页(Profile),希望从登录页成功登录后,跳转到个人中心页。同时,销毁登录页,在返回时直接退出应用。

此时直接replaceUrl方法会在跳转的同时,销毁登录页,在上面的例子中,直接将pushUrl换成replaceUrl即可。

import router from'@ohos.router';
 
Button("查看详情").onClick(() => {
  router.replaceUrl({ url: 'pages/HmDetail' })
  })
})
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

总结

(1)当你需要跳转之后,还可以回到上一个页面,使用pushUrl,它会保留当前的页面,压一个新的页面

(2)当你跳转之后,上一个页面的任务已经完成,不需要返回,就可以使用replaceUrl

3.  back返回

router.back() . 返回上一个页面,此时不需要参数,如果说你想要返回的时候带一些参数,需要params和url- 想要指定url.

(1)router.back()

在详情页加一个返回按钮,点击按钮调用router.back()。

import router from '@ohos.router'
Button("返回列表页")
   .onClick(() => {
      router.back()
})
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

添加一个返回按钮,完整代码如下:

import router from '@ohos.router'
@Entry
@Component
struct HmDetail {

  build() {
    Column(){
      Row(){
        Text("详情页")
          .width('100%')
          .textAlign(TextAlign.Center)
      }.height(40)
      .border({
        color: '#f3f4f5',
        width: {
          bottom: 1
        }
      })

      Column(){
        Text("详情页")
          .fontSize(50)
        Button("返回列表页")
          .onClick(()=> {
            router.back()
          })
      }
      .layoutWeight(1)
      .justifyContent(FlexAlign.Center)
    }
    .height('100%')
  }
}
  • 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.


实现效果,如图所示。

HarmonyOS页面路由-鸿蒙开发者社区

4.  路由参数

如果需要在跳转时,传递一些数据给目标页,比如列表页到详情页,想把id传过去,就可以使用路由传参的模式。

(1)修改HmList.ets文件,代码如下:

Button("查看详情").onClick(() => {
      router.pushUrl({
          url: 'pages/HmDetail',
              params: {
                    id: item.id
              }
           })
       })
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

(2)修改HmDetail.ets文件,子组件接收参数,代码如下:

import router from '@ohos.router'

class RouterParams {
  id: number = 0
}
    
@Entry
@Component
struct HmDetail {
  @State
  detailId: number = 0
  aboutToAppear() {
    const params = router.getParams() as RouterParams
    if(params?.id) {
      this.detailId = params?.id
    }
  }

  build() {
    Column(){
      Row(){
        Text("详情页")
          .width('100%')
          .textAlign(TextAlign.Center)
      }.height(40)
      .border({
        color: '#f3f4f5',
        width: {
          bottom: 1
        }
      })
      Column(){
        Text("详情页 " + this.detailId)
          .fontSize(50)
        Button("返回列表页")
          .onClick(()=> {
            router.back()
          })
      }
      .layoutWeight(1)
      .justifyContent(FlexAlign.Center)
    }
    .height('100%')
  }
}
  • 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.

实现效果,如图所示。

HarmonyOS页面路由-鸿蒙开发者社区

router.back() 同样可以传递参数给上一级的路由,上一级路由应该在onPageShow里面接收详情页面返回传参。

(1)HmDetail.ets文件,详情组件添加“返回列表页带参数”按钮,代码如下:

Button("返回列表页带参数")
         .onClick(() => {
           router.back({
             url: 'pages/HmList',
             params: {
               backId: this.detailId
             }
           })
         })
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

(2)父组件接受参数,HmList.ets文件,代码如下:

class BackRouterParams {
  backId: number = 0
}
onPageShow() {
   const params = router.getParams() asBackRouterParams
    if(params?.backId) {
      AlertDialog.show({
        message: params.backId.toString()
      })
    }
  }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

完整代码如下:

import router from '@ohos.router'

class ListItemInfo {
  title: string = ""
  id: number = 0
}

class BackRouterParams {
  backId: number = 0
}


@Entry
@Component
struct HmList {
  @State list: ListItemInfo[]= Array.from(Array(100),(_: number, index:number) => {
    return {
      title: `我是第${index +1}个`,
      id: index + 1
    } as ListItemInfo
  })
  onPageShow() {
    const params = router.getParams() as BackRouterParams
    if(params?.backId) {
      AlertDialog.show({
        message: params.backId.toString()
      })
    }
  }
  build() {
    Column({space: 20 }) {
      Row(){
        Text("列表数据")
          .textAlign(TextAlign.Center)
          .width('100%')
          .height(40)
      } .border({
        color: '#f3f4f5',
        width: {
          bottom: 1
        }
      })
      List({space: 10 }) {
        ForEach(this.list, (item: ListItemInfo) => {
          ListItem () {
            Row(){
              Text(item.title)
              Button("查看详情").onClick(()=> {
                // router.pushUrl({ url: 'pages/HmDetail' })
                // router.replaceUrl({ url: 'pages/HmDetail' })
                router.pushUrl({
                  url: 'pages/HmDetail',
                  params: {
                    id: item.id
                  }
                })
              })
                .height(30)
            }.width('100%')
            .justifyContent(FlexAlign.SpaceBetween)
            .padding({
              left: 10,
              right: 10
           })
          }
        })
      }
    }
  }
}
  • 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.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.


实现效果,如图所示。

HarmonyOS页面路由-鸿蒙开发者社区

总结:

(1)传参用params对象,里面可以传任意内容,key/value由开发者自己定义。

(2)接收端采用router.getParams()获取对象,需要通过class来定义参数的结构,接收之后通过类型断言as指定为具体类型。

(3)如果是通过pushUrl的方式跳转的,返回上一个页面时,aboutToAppear不会执行,需要使用onPageShow来监听当前页面的显示钩子函数。

5.  路由模式

Standard:标准实例模式,也是默认情况下的实例模式。每次调用该方法都会新建一个目标页,并压入栈顶。

Single:单实例模式。即如果目标页的url在页面栈中已经存在同url页面,则离栈顶最近的同url页面会被移动到栈顶,并重新加载;如果目标页的url在页面栈中不存在同url页面,则按照标准模式跳转。

简单理解一下就是:

(1)Standard-只要push,页面栈里面就会加一项,不管之前加没加过。

(2)Single- 之前加过,不会加新的页面,会把之前加过的页面加出来。

测试- 在detail页面再push到list页,分别使用单例模式和标准模式测试。

 

Button("标准模式")
         .onClick(() => {
           router.pushUrl({
             url: 'pages/HmList'
           })
         })
       Button("单例模式")
         .onClick(() => {
           router.pushUrl({
             url: 'pages/HmList'
           }, router.RouterMode.Single)
         })
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

这里会发现 使用single模式路由返回时的list已经不存在了,因为单例模式只要存在不会再压栈。

HmDetail.ets文件,完整代码如下:

import router from '@ohos.router'
class RouterParams {
  id: number = 0
}

@Entry
@Component
struct HmDetail {

  @State
  detailId: number = 0
  aboutToAppear() {
    const params = router.getParams() as RouterParams
    if(params?.id) {
      this.detailId = params?.id
    }
  }

  build() {
    Column(){
      Row(){
        Text("详情页")
          .width('100%')
          .textAlign(TextAlign.Center)
      }.height(40)
      .border({
        color: '#f3f4f5',
        width: {
          bottom: 1
        }
      })

      Column(){
        Text("详情页" + this.detailId)
          .fontSize(50)
        Button("返回列表页")
          .onClick(()=> {
            router.back()
          })
        Button("返回列表页带参数")
          .onClick(()=> {
            router.back({
              url: 'pages/HmList',
              params: {
                backId: this.detailId
              }
            })
          })
        Button("标准模式")
          .onClick(()=> {
            router.pushUrl({
              url: 'pages/HmList'
            })
          })
        Button("单例模式")
          .onClick(()=> {
            router.pushUrl({
              url: 'pages/HmList'
            }, router.RouterMode.Single)
          })

      }
      .layoutWeight(1)
      .justifyContent(FlexAlign.Center)
    }
    .height('100%')
  }
}
  • 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.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.

实现效果,如图所示。

 

 

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
MyApplication_router.rar 941.45K 0次下载
收藏
回复
举报
回复
    相关推荐