鸿蒙开发0基础【页面路由 (@ohos.router)】ArkUI

页面路由指在应用程序中实现不同页面之间的跳转和数据传递。Router模块通过不同的url地址,可以方便地进行页面路由,轻松地访问不同的页面。

页面跳转

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

图1 页面跳转

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Router模块提供了两种跳转模式,分别是[router.pushUrl]和[router.replaceUrl]。这两种模式决定了目标页面是否会替换当前页。

  • router.pushUrl:目标页面不会替换当前页,而是压入页面栈。这样可以保留当前页的状态,并且可以通过返回键或者调用[router.back]方法返回到当前页。
  • router.replaceUrl:目标页面会替换当前页,并销毁当前页。这样可以释放当前页的资源,并且无法返回到当前页。

同时,Router模块提供了两种实例模式,分别是Standard和Single。这两种模式决定了目标url是否会对应多个实例。

  • Standard:多实例模式,也是默认情况下的跳转模式。目标页面会被添加到页面栈顶,无论栈中是否存在相同url的页面。
  • Single:单实例模式。如果目标页面的url已经存在于页面栈中,则会将离栈顶最近的同url页面移动到栈顶,该页面成为新建页。如果目标页面的url在页面栈中不存在同url页面,则按照默认的多实例模式进行跳转。

在使用Router相关功能之前,需要在代码中先导入Router模块。

import { promptAction, router } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';
  • 场景一:有一个主页(Home)和一个详情页(Detail),希望从主页点击一个商品,跳转到详情页。同时,需要保留主页在页面栈中,以便返回时恢复状态。这种场景下,可以使用pushUrl方法,并且使用Standard实例模式(或者省略)。
import { router } from '@kit.ArkUI';

// 在Home页面中
function onJumpClick(): void {
  router.pushUrl({
    url: 'pages/Detail' // 目标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.');
  });
}

说明

多实例模式下,router.RouterMode.Standard参数可以省略。

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

// 在Login页面中
function onJumpClick(): void {
  router.replaceUrl({
    url: 'pages/Profile' // 目标url
  }, 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.');
  })
}

说明

多实例模式下,router.RouterMode.Standard参数可以省略。

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

// 在Setting页面中
function onJumpClick(): void {
  router.pushUrl({
    url: 'pages/Theme' // 目标url
  }, 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实例模式。
import { router } from '@kit.ArkUI';

// 在SearchResult页面中
function onJumpClick(): void {
  router.replaceUrl({
    url: 'pages/SearchDetail' // 目标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属性,并指定一个对象作为参数。例如:

import { router } from '@kit.ArkUI';

class DataModelInfo {
  age: number = 0;
}

class DataModel {
  id: number = 0;
  info: DataModelInfo | null = null;
}

function onJumpClick(): void {
  // 在Home页面中
  let paramsInfo: DataModel = {
    id: 123,
    info: {
      age: 20
    }
  };

  router.pushUrl({
    url: 'pages/Detail', // 目标url
    params: paramsInfo // 添加params属性,传递自定义参数
  }, (err) => {
    if (err) {
      console.error(`Invoke pushUrl failed, code is ${err.code}, message is ${err.message}`);
      return;
    }
    console.info('Invoke pushUrl succeeded.');
  })
}

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

import { router } from '@kit.ArkUI';

class InfoTmp {
  age: number = 0
}

class RouTmp {
  id: object = () => {
  }
  info: InfoTmp = new InfoTmp()
}

const params: RouTmp = router.getParams() as RouTmp; // 获取传递过来的参数对象
const id: object = params.id // 获取id属性的值
const age: number = params.info.age // 获取age属性的值

页面返回

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

图2 页面返回

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在使用页面路由Router相关功能之前,需要在代码中先导入Router模块。

import { router } from '@kit.ArkUI';

可以使用以下几种方式返回页面:

  • 方式一:返回到上一个页面。
import { router } from '@kit.ArkUI';

router.back();

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

  • 方式二:返回到指定页面。

返回普通页面。

import { router } from '@kit.ArkUI';

router.back({
  url: 'pages/Home'
});

返回命名路由页面。

import { router } from '@kit.ArkUI';

router.back({
  url: 'myPage' //myPage为返回的命名路由页面别名
});

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

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

返回到普通页面。

import { router } from '@kit.ArkUI';

router.back({
  url: 'pages/Home',
  params: {
    info: '来自Home页'
  }
});

返回命名路由页面。

import { router } from '@kit.ArkUI';

router.back({
  url: 'myPage', //myPage为返回的命名路由页面别名
  params: {
    info: '来自Home页'
  }
});

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

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

@Entry
@Component
struct Home {
  @State message: string = 'Hello World';

  onPageShow() {
    const params = this.getUIContext().getRouter().getParams() as Record<string, string>; // 获取传递过来的参数对象
    if (params) {
      const info: string = params.info as string; // 获取info属性的值
    }
  }

  // ...
}

说明

当使用router.back方法返回到指定页面时,原栈顶页面(包括)到指定页面(不包括)之间的所有页面栈都将从栈中弹出并销毁。

另外,如果使用router.back方法返回到原来的页面,原页面不会被重复创建,因此使用@State声明的变量不会重复声明,也不会触发页面的aboutToAppear生命周期回调。如果需要在原页面中使用返回页面传递的自定义参数,可以在需要的位置进行参数解析。例如,在onPageShow生命周期回调中进行参数解析。

页面返回前增加一个询问框

在开发应用时,为了避免用户误操作或者丢失数据,有时候需要在用户从一个页面返回到另一个页面之前,弹出一个询问框,让用户确认是否要执行这个操作。

本文将从[系统默认询问框]和[自定义询问框]两个方面来介绍如何实现页面返回前增加一个询问框的功能。

图3 页面返回前增加一个询问框

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

系统默认询问框

为了实现这个功能,可以使用页面路由Router模块提供的两个方法:[router.showAlertBeforeBackPage]和[router.back]来实现这个功能。

在使用页面路由Router相关功能之前,需要在代码中先导入Router模块。

import { router } from '@kit.ArkUI';

如果想要在目标界面开启页面返回询问框,需要在调用[router.back]方法之前,通过调用[router.showAlertBeforeBackPage]方法设置返回询问框的信息。例如,在支付页面中定义一个返回按钮的点击事件处理函数:

import { router } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';

// 定义一个返回按钮的点击事件处理函数
function onBackClick(): void {
  // 调用router.showAlertBeforeBackPage()方法,设置返回询问框的信息
  try {
    router.showAlertBeforeBackPage({
      message: '您还没有完成支付,确定要返回吗?' // 设置询问框的内容
    });
  } catch (err) {
    let message = (err as BusinessError).message
    let code = (err as BusinessError).code
    console.error(`Invoke showAlertBeforeBackPage failed, code is ${code}, message is ${message}`);
  }

  // 调用router.back()方法,返回上一个页面
  router.back();
}

其中,router.showAlertBeforeBackPage方法接收一个对象作为参数,该对象包含以下属性:

message:string类型,表示询问框的内容。

如果调用成功,则会在目标界面开启页面返回询问框;如果调用失败,则会抛出异常,并通过err.code和err.message获取错误码和错误信息。

当用户点击“返回”按钮时,会弹出确认对话框,询问用户是否确认返回。选择“取消”将停留在当前页目标页面;选择“确认”将触发router.back方法,并根据参数决定如何执行跳转。

自定义询问框

自定义询问框的方式,可以使用弹窗[promptAction.showDialog]或者自定义弹窗实现。这样可以让应用界面与系统默认询问框有所区别,提高应用的用户体验度。本文以弹窗为例,介绍如何实现自定义询问框。

在使用页面路由Router相关功能之前,需要在代码中先导入Router模块。

import { router } from '@kit.ArkUI';

在事件回调中,调用弹窗的[promptAction.showDialog]方法:

import { promptAction, router } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';

function onBackClick() {
  // 弹出自定义的询问框
  promptAction.showDialog({
    message: '您还没有完成支付,确定要返回吗?',
    buttons: [
      {
        text: '取消',
        color: '#FF0000'
      },
      {
        text: '确认',
        color: '#0099FF'
      }
    ]
  }).then((result: promptAction.ShowDialogSuccessResponse) => {
    if (result.index === 0) {
      // 用户点击了“取消”按钮
      console.info('User canceled the operation.');
    } else if (result.index === 1) {
      // 用户点击了“确认”按钮
      console.info('User confirmed the operation.');
      // 调用router.back()方法,返回上一个页面
      router.back();
    }
  }).catch((err: Error) => {
    let message = (err as BusinessError).message
    let code = (err as BusinessError).code
    console.error(`Invoke showDialog failed, code is ${code}, message is ${message}`);
  })
}

当用户点击“返回”按钮时,会弹出自定义的询问框,询问用户是否确认返回。选择“取消”将停留在当前页目标页面;选择“确认”将触发router.back方法,并根据参数决定如何执行跳转。

命名路由

在开发中为了跳转到共享包[HAR]或者[HSP]中的页面(即共享包中路由跳转),可以使用[router.pushNamedRoute]来实现。

图4 命名路由跳转

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在使用页面路由Router相关功能之前,需要在代码中先导入Router模块。

import { router } from '@kit.ArkUI';

在想要跳转到的共享包[HAR]或者[HSP]页面里,给@Entry修饰的自定义组件[EntryOptions]命名:

// library/src/main/ets/pages/Index.ets
// library为新建共享包自定义的名字
@Entry({ routeName: 'myPage' })
@Component
export struct MyComponent {
  build() {
    Row() {
      Column() {
        Text('Library Page')
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
      }
      .width('100%')
    }
    .height('100%')
  }
}

配置成功后需要在跳转的页面中引入命名路由的页面:

import { BusinessError } from '@kit.BasicServicesKit';
import '@ohos/library/src/main/ets/pages/Index'; // 引入共享包中的命名路由页面

@Entry
@Component
struct Index {
  build() {
    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
      Text('Hello World')
        .fontSize(50)
        .fontWeight(FontWeight.Bold)
        .margin({ top: 20 })
        .backgroundColor('#ccc')
        .onClick(() => { // 点击跳转到其他共享包中的页面
          try {
            this.getUIContext().getRouter().pushNamedRoute({
              name: 'myPage',
              params: {
                data1: 'message',
                data2: {
                  data3: [123, 456, 789]
                }
              }
            })
          } catch (err) {
            let message = (err as BusinessError).message
            let code = (err as BusinessError).code
            console.error(`pushNamedRoute failed, code is ${code}, message is ${message}`);
          }
        })
    }
    .width('100%')
    .height('100%')
  }
}

说明

使用命名路由方式跳转时,需要在当前应用包的oh-package.json5文件中配置依赖。例如:

"dependencies": {
   "@ohos/library": "file:../library",
   ...
}
<think>好的,我需要回答用户关于鸿蒙开发路由实现方案的问题。首先,我要仔细阅读用户提供的引用内容,特别是引用[3]和[4],这两个引用提到了路由模块的依赖配置,比如在oh-package.json5中添加@ohos/dynamicsrouter或@hadss/hmrouter的依赖。用户可能想知道如何在鸿蒙项目中配置和使用路由。 接下来,用户的问题是关于路由的实现方法,所以我要结合引用中的信息,整理出具体的步骤。可能需要包括路由模块的配置、静态路由和动态路由的使用方法,以及路由参数传递和拦截器机制。此外,引用[2]提到ArkTS、ArkUI开发组件和Stage模型,这些可能在路由实现中起到作用,需要适当提及。 需要注意的是,系统级指令要求使用中文回答,并且正确使用LaTeX格式的数学表达式,但在这个问题中可能涉及代码和配置示例,所以重点在于代码块的正确展示。同时,生成的相关问题需要与路由开发相关,比如性能优化、多端部署中的路由适配等。 然后,我需要检查引用标识是否正确添加,比如在提到依赖配置时引用[3]和[4],在核心知识部分引用[2]。回答结构要清晰,分步骤说明实现方案,确保用户能够逐步理解和应用。 最后,确保相关问题的生成符合用户可能感兴趣的后续学习方向,例如路由优化、与分布式应用开发的结合等。同时,代码示例要准确,符合鸿蒙开发的规范,比如使用ArkTS语言和Stage模型的结构。</think>在鸿蒙HarmonyOS开发中,路由实现方案主要基于 **动态路由模块** 和 **ArkUI框架**,以下是具体实现方法: --- ### 一、路由模块配置 1. **依赖声明** 在模块的`oh-package.json5`中添加路由模块依赖: ```json { "dependencies": { "@ohos/dynamicsrouter": "file:../../common/routermodule", // 动态路由模块[^3] "@hadss/hmrouter": "^1.0.0-rc.6" // 第三方路由库[^4] } } ``` 2. **编译插件配置** 在`build-profile.json5`中启用路由插件支持: ```json { "plugins": [ { "name": "@hadss/hmrouter-plugin" } ] } ``` --- ### 二、路由实现方案 #### 1. **静态路由声明** 在`ets`文件中定义路由表: ```typescript // routes.ets export const routes = [ { path: '/home', component: HomePage // 静态导入页面组件 }, { path: '/detail/:id', // 动态参数路由 component: () => import('pages/DetailPage') // 懒加载组件 } ]; ``` #### 2. **动态路由跳转** 使用`Router`模块进行导航: ```typescript import { Router } from '@ohos/dynamicsrouter'; // 基础跳转 Router.pushUrl({ url: 'pages/HomePage' }); // 带参数跳转 Router.pushUrl({ url: 'pages/DetailPage', params: { id: 123 } }); ``` #### 3. **路由拦截器** 通过路由守卫实现权限控制: ```typescript Router.addInterceptor((to, from, next) => { if (to.url === '/profile' && !isLogin) { next('/login'); // 未登录跳转登录页 } else { next(); } }); ``` --- ### 三、核心机制解析 - **Stage模型支持**:路由模块深度集成Stage模型,通过`UIAbility`实现跨页面通信[^2]。 - **跨端适配**:通过`@ohos/dynamicsrouter`支持多端部署时路由策略自动适配[^2]。 - **性能优化**:懒加载(`import()`语法)减少首屏资源加载量。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值