您的位置:首页 > 娱乐 > 八卦 > HarmonyOS 页面路由(Router)

HarmonyOS 页面路由(Router)

2024/12/23 1:48:50 来源:https://blog.csdn.net/qq_36158551/article/details/139767796  浏览:    关键词:HarmonyOS 页面路由(Router)

1. HarmonyOS页面路由(Router)

  页面路由指在应用程序中实现不同页面之间的跳转和数据传递。HarmonyOS提供了Router模块,通过不同的url地址,可以方便地进行页面路由,轻松地访问不同的页面。本文将从页面跳转、页面返回和页面返回前增加一个询问框几个方面介绍Router模块提供的功能。
在这里插入图片描述在这里插入图片描述

1.1. 页面跳转

  页面跳转是开发过程中的一个重要组成部分。在使用应用程序时,通常需要在不同的页面之间跳转,有时还需要将数据从一个页面传递到另一个页面。

1.1.1. 跳转模式

  Router模块提供了两种跳转模式,分别是router.pushUrl()和router.replaceUrl()。这两种模式决定了目标页是否会替换当前页。
(1)router.pushUrl():目标页不会替换当前页,而是压入页面栈。这样可以保留当前页的状态,并且可以通过返回键或者调用router.back()方法返回到当前页。
(2)router.replaceUrl():目标页会替换当前页,并销毁当前页。这样可以释放当前页的资源,并且无法返回到当前页。
  说明:页面栈的最大容量为32个页面。如果超过这个限制,可以调用router.clear()方法清空历史页面栈,释放内存空间。

1.1.2.实例模式

  Router模块提供了两种实例模式,分别是Standard和Single。这两种模式决定了目标url是否会对应多个实例。
(1)Standard:标准实例模式,也是默认情况下的实例模式。每次调用该方法都会新建一个目标页,并压入栈顶。
(2)Single:单实例模式。即如果目标页的url在页面栈中已经存在同url页面,则离栈顶最近的同url页面会被移动到栈顶,并重新加载;如果目标页的url在页面栈中不存在同url页面,则按照标准模式跳转。

1.2. 场景

1.2.1.场景一

  有一个主页(Home)和一个详情页(Detail),希望从主页点击一个商品,跳转到详情页。同时,需要保留主页在页面栈中,以便返回时恢复状态。这种场景下,可以使用pushUrl()方法,并且使用Standard实例模式(或者省略)。标准实例模式下,router.RouterMode.Standard参数可以省略。

 private standardClick() {router.pushUrl({url: 'pages/myTool/RouterTwoPage' // 目标url}, router.RouterMode.Standard, (err) => {if (err) {console.error(`Invoke pushUrl failed, code is ${err.code},message is ${err.message}`);return;}console.info('Invoke pushUrl succeeded.');});}

1.2.2.场景二

  有一个登录页(Login)和一个个人中心页(Profile),希望从登录页成功登录后,跳转到个人中心页。同时,销毁登录页,在返回时直接退出应用。这种场景下,可以使用replaceUrl()方法,并且使用Standard实例模式(或者省略)。

  private standardReplaceClick() {router.replaceUrl({url: 'pages/myTool/RouterTwoPage'}, router.RouterMode.Standard, (err) => {if (err) {console.error(`Invoke replaceUrl failed, code is ${err.code},message is ${err.message}`);return;}console.info('Invoke replaceUrl succeeded.');})}

1.2.3.场景三

  有一个设置页(Setting)和一个主题切换页(Theme),希望从设置页点击主题选项,跳转到主题切换页。同时,需要保证每次只有一个主题切换页存在于页面栈中,在返回时直接回到设置页。这种场景下,可以使用pushUrl()方法,并且使用Single实例模式。

  private singleClick() {router.pushUrl({url: 'pages/myTool/RouterTwoPage'}, router.RouterMode.Single, (err) => {if (err) {console.error(`Invoke pushUrl failed, code is ${err.code},message is ${err.message}`);return;}console.info('Invoke pushUrl succeeded.');});}

1.2.4.场景四

  有一个搜索结果列表页(SearchResult)和一个搜索结果详情页(SearchDetail),希望从搜索结果列表页点击某一项结果,跳转到搜索结果详情页。同时,如果该结果已经被查看过,则不需要再新建一个详情页,而是直接跳转到已经存在的详情页。这种场景下,可以使用replaceUrl()方法,并且使用Single实例模式。

  private single2Click() {router.replaceUrl({url: 'pages/myTool/RouterTwoPage' // 目标url}, router.RouterMode.Single, (err) => {if (err) {console.error(`Invoke replaceUrl failed, code is ${err.code},message is ${err.message}`);return;}console.info('Invoke replaceUrl succeeded.');})
}

1.2.5.场景五

  如果需要在跳转时传递一些数据给目标页,则可以在调用Router模块的方法时,添加一个params属性,并指定一个对象作为参数。例如:
(1)RouterBean

export class RouterItemBean {id?: stringtitle?: string
}
export class RouterBean {mainId?: string;routerItemBean?: RouterItemBean;
}

(2)带参跳转

 private paramsClick() {let paramsInfo: RouterBean = {mainId: "123",routerItemBean: {id: "456",title: "789",}};router.pushUrl({url: 'pages/myTool/RouterTwoPage', // 目标urlparams: paramsInfo // 添加params属性,传递自定义参数}, (err) => {if (err) {console.error(`Invoke pushUrl failed, code is ${err.code},message is ${err.message}`);return;}console.info('Invoke pushUrl succeeded.');})}

(3)在目标页中,可以通过调用Router模块的getParams()方法来获取传递过来的参数。例如:

aboutToAppear() {try {// 获取传递过来的参数对象this.routerBean =  (router.getParams() as RouterBean);let  mainId =  this.routerBean.mainId;let  routerItem =  this.routerBean.routerItem;let  id = routerItem?.id;let  title = routerItem?.title;this.msg="获取传过来的数据:"+mainId+id+title} catch (e) {}}

1.3.页面返回

  当用户在一个页面完成操作后,通常需要返回到上一个页面或者指定页面,这就需要用到页面返回功能。在返回的过程中,可能需要将数据传递给目标页,这就需要用到数据传递功能。

1.3.1.方式一: 返回到上一个页面

  这种方式会返回到上一个页面,即上一个页面在页面栈中的位置。但是,上一个页面必须存在于页面栈中才能够返回,否则该方法将无效。

  private routerClick() {//router.back(2)router.back()}

1.3.2.方式二:返回到指定页面

  这种方式可以返回到指定页面,需要指定目标页的路径。目标页必须存在于页面栈中才能够返回。

  private back2Click() {router.back({url: 'pages/myTool/RouterOnePage'});}

1.3.3.方式三:返回到指定页面,并传递自定义参数信息

  这种方式不仅可以返回到指定页面,还可以在返回的同时传递自定义参数信息。这些参数信息可以在目标页中通过调用router.getParams()方法进行获取和解析。

  private back3Click() {let paramsInfo: RouterBean = {mainId: "111",routerItem: {id: "222",title: "333",},};router.back({url: 'pages/myTool/RouterOnePage',params: paramsInfo});}

  在目标页中,在需要获取参数的位置调用router.getParams()方法即可,例如在onPageShow()生命周期回调中:

  onPageShow() {try {// 获取传递过来的参数对象this.routerBean =  (router.getParams() as RouterBean);let  mainId =  this.routerBean.mainId;let  routerItem =  this.routerBean.routerItem;let  id = routerItem?.id;let  title = routerItem?.title;this.msg="获取传过来的数据:"+mainId+id+title} catch (e) {}}

  当使用router.back()方法返回到指定页面时,原栈顶页面(包括)到指定页面(不包括)之间的所有页面栈都将从栈中弹出并销毁。
  另外,如果使用router.back()方法返回到原来的页面,原页面不会被重复创建,因此使用@State声明的变量不会重复声明,也不会触发页面的aboutToAppear()生命周期回调。如果需要在原页面中使用返回页面传递的自定义参数,可以在需要的位置进行参数解析。例如,在onPageShow()生命周期回调中进行参数解析。

1.4.完整代码

1.4.1.RouterBean.ets


export class RouterItem {id?: stringtitle?: string
}export class RouterArr {array?:string[]
}export class RouterBean {mainId?: string;routerItem?: RouterItem;routerArr?: RouterArr;
}

1.4.2.RouterOnePage.ets

import { TitleBar } from '../../components/common/TitleBar'
import { router } from '@kit.ArkUI'
import { RouterParams } from '../../helper/RouterHelper'
import { BusinessError } from '@kit.BasicServicesKit'
import { Logger } from '../../utils/Logger'
import { RouterBean } from '../../bean/RouterBean'@Extend(Button)
function buttonItem() {.stateEffect(true).type(ButtonType.Normal).borderRadius(8).fontSize(17).backgroundColor($r('app.color.primary_green')).padding({top: 8,bottom: 8,left: 70,right: 70}).margin({top: 15,bottom: 15})
}@Entry
@Component
struct RouterOnePage {@State pageTitle: string = "路由跳转"private routerBean?: RouterBeanprivate msg: string = '3f3d4 'aboutToAppear() {try {this.pageTitle = (router.getParams() as RouterParams).title} catch (e) {}}onPageShow() {try {// 获取传递过来的参数对象this.routerBean =  (router.getParams() as RouterBean);let  mainId =  this.routerBean.mainId;let  routerItem =  this.routerBean.routerItem;let  id = routerItem?.id;let  title = routerItem?.title;this.msg="获取传过来的数据:"+mainId+id+title} catch (e) {}}/*** router.pushUrl()*/async routerClick() {//router.pushUrl()//目标页面不会替换当前页,而是压入页面栈。// 这样可以保留当前页的状态,并且可以通过返回键// 或者调用router.back()方法返回到当前页。let options: router.RouterOptions = {url: 'pages/myTool/RouterTwoPage',params: new RouterParams("路由跳转", [12, 45, 78])}try {await router.pushUrl(options)} catch (err) {console.info(` fail callback,code: ${(err as BusinessError).code},msg: ${(err as BusinessError).message}`)}}/*** router.replaceUrl()*/async replaceRouterClick() {router.replaceUrl({ url: 'pages/myTool/RouterTwoPage' }).catch((err: Error) => {Logger.error(JSON.stringify(err));})}/***有一个主页(Home)和一个详情页(Detail),* 希望从主页点击一个商品,跳转到详情页。* 同时,需要保留主页在页面栈中,以便返回时恢复状态。* 这种场景下,可以使用pushUrl()方法,* 并且使用Standard实例模式(或者省略)。*/private standardClick() {router.pushUrl({url: 'pages/myTool/RouterTwoPage' // 目标url}, router.RouterMode.Standard, (err) => {if (err) {console.error(`Invoke pushUrl failed, code is ${err.code},message is ${err.message}`);return;}console.info('Invoke pushUrl succeeded.');});}/*** 有一个登录页(Login)和一个个人中心页(Profile),* 希望从登录页成功登录后,跳转到个人中心页。* 同时,销毁登录页,在返回时直接退出应用。* 这种场景下,可以使用replaceUrl()方法,* 并且使用Standard实例模式(或者省略)。*/private standardReplaceClick() {router.replaceUrl({url: 'pages/myTool/RouterTwoPage'}, router.RouterMode.Standard, (err) => {if (err) {console.error(`Invoke replaceUrl failed, code is ${err.code},message is ${err.message}`);return;}console.info('Invoke replaceUrl succeeded.');})}/*** 有一个设置页(Setting)和一个主题切换页(Theme),* 希望从设置页点击主题选项,跳转到主题切换页。* 同时,需要保证每次只有一个主题切换页存在于页面栈中,* 在返回时直接回到设置页。这种场景下,可以使用pushUrl()方法,* 并且使用Single实例模式。*/private singleClick() {router.pushUrl({url: 'pages/myTool/RouterTwoPage'}, router.RouterMode.Single, (err) => {if (err) {console.error(`Invoke pushUrl failed, code is ${err.code},message is ${err.message}`);return;}console.info('Invoke pushUrl succeeded.');});}/***有一个搜索结果列表页(SearchResult)和一个搜索结果详情页(SearchDetail),* 希望从搜索结果列表页点击某一项结果,跳转到搜索结果详情页。* 同时,如果该结果已经被查看过,则不需要再新建一个详情页,* 而是直接跳转到已经存在的详情页。这种场景下,可以使用replaceUrl()方法,* 并且使用Single实例模式。*/private single2Click() {router.replaceUrl({url: 'pages/myTool/RouterTwoPage' // 目标url}, router.RouterMode.Single, (err) => {if (err) {console.error(`Invoke replaceUrl failed, code is ${err.code},message is ${err.message}`);return;}console.info('Invoke replaceUrl succeeded.');})}/***如果需要在跳转时传递一些数据给目标页,则可以在调用Router模块的方法时,* 添加一个params属性,并指定一个对象作为参数。例如:*/private paramsClick() {let paramsInfo: RouterBean = {mainId: "123",routerItem: {id: "456",title: "789",},};router.pushUrl({url: 'pages/myTool/RouterTwoPage', // 目标urlparams: paramsInfo // 添加params属性,传递自定义参数}, (err) => {if (err) {console.error(`Invoke pushUrl failed, code is ${err.code},message is ${err.message}`);return;}console.info('Invoke pushUrl succeeded.');})}build() {Column() {TitleBar({ pageTitle: $pageTitle })Button('路由跳转').buttonItem().onClick(this.routerClick)Button('销毁跳转').buttonItem().onClick(this.replaceRouterClick)Button('standard').buttonItem().onClick(this.standardClick)Button('standardReplace').buttonItem().onClick(this.standardReplaceClick)Button('single').buttonItem().onClick(this.singleClick)Button('single2').buttonItem().onClick(this.single2Click)Button('带参路由').buttonItem().onClick(this.paramsClick)Text(this.msg).fontSize(18).fontColor($r('app.color.primary_font_title')).margin({ top: 20 })}.height('100%')}
}

1.4.3.RouterTwoPage.ets

import { TitleBar } from '../../components/common/TitleBar'
import { router } from '@kit.ArkUI'
import { RouterParams } from '../../helper/RouterHelper'
import { BusinessError } from '@kit.BasicServicesKit'
import { Logger } from '../../utils/Logger'
import { RouterBean } from '../../bean/RouterBean'@Extend(Button)
function buttonItem() {.stateEffect(true).type(ButtonType.Normal).borderRadius(8).fontSize(17).backgroundColor($r('app.color.primary_green')).padding({top: 8,bottom: 8,left: 70,right: 70}).margin({top: 15,bottom: 15})
}@Entry
@Component
struct RouterTwoPage {@State pageTitle: string = "路由跳转二"private routerBean?: RouterBeanprivate msg: string = '3f3d4 'aboutToAppear() {try {// 获取传递过来的参数对象this.routerBean =  (router.getParams() as RouterBean);let  mainId =  this.routerBean.mainId;let  routerItem =  this.routerBean.routerItem;let  id = routerItem?.id;let  title = routerItem?.title;this.msg="获取传过来的数据:"+mainId+id+title} catch (e) {}}/*** 返回到上一个页面*/private backClick() {//router.back(2)router.back()}/*** 返回指定页面*/private back2Click() {router.back({url: 'pages/myTool/RouterOnePage'});}/***  返回到指定页面,并传递自定义参数信息*/private back3Click() {let paramsInfo: RouterBean = {mainId: "111",routerItem: {id: "222",title: "333",},};router.back({url: 'pages/myTool/RouterOnePage',params: paramsInfo});}build() {Column() {TitleBar({ pageTitle: $pageTitle })Button('返回到上一个页面').buttonItem().onClick(this.backClick)Button('返回指定页面').buttonItem().onClick(this.back2Click)Button('传参返回').buttonItem().onClick(this.back3Click)Text(this.msg).fontSize(18).fontColor($r('app.color.primary_font_title')).margin({ top: 20 })}.height('100%')}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com