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?: string
  title?: 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', // 目标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.');
    })
  }

(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?: string
  title?: 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?: RouterBean
  private 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', // 目标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.');
    })
  }

  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?: RouterBean
  private 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%')
  }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/720203.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python安装失败,报0x80070643-安装时发生严重错误。

背景 之前安装了3.12.4,因为没用到,就用Revo Uninstaller Pro卸载了,连注册表都清理了。后面看到别人写的一个工具不符合预期,想对源码修改下,用到了Python,于是重新安装,出现上面报错。 解决方法尝试 因…

在Pycharm使用Github Copilot

文章目录 1.GitHub Copilot 是什么2.注册GitHub Copilot3.官方使用文档4.安装 GitHub Copilot插件5.在Pycharm中使用6.相关功能键7.启用或禁用 GitHub Copilot 1.GitHub Copilot 是什么 GitHub Copilot 是一款 AI 编码助手,可帮助你更快、更省力地编写代码&#xff…

基于javassm实现的物流管理系统

开发语言:Java 框架:ssm 数据库:mysql 系统页面展示 4.1登陆页面 平台登录:主要是做权限分配和安全限制等操作。可以把快递员,客户,派单员等人员角色区分开来。 4.2注册页面 用户注册界面:…

固定式土壤墒情监测仪—土壤状况进行长期跟踪和分析

TH-TS600 固定式土壤墒情监测仪是一种专门用于长期、连续、自动监测土壤墒情的设备。能够实时监测土壤的水分、温度、湿度等关键参数,确保农民和管理者能即时获取土壤状况信息,便于及时做出农业决策。由于是自动监测,数据采集的准确性和可靠性…

目标检测数据集 - 手机屏幕表面表面缺陷检测数据集下载「包含VOC、COCO、YOLO三种格式」

数据集介绍:手机屏幕表面缺陷检测数据集,真实采集高质量手机屏幕表面含缺陷图片数据,数据集含多款不同型号和品牌的手机屏幕表面图片数据,包括苹果手机屏、三星手机屏、华为手机屏等数据。数据标注标签包括 Bubble 气泡/水滴、Scr…

动手学深度学习(Pytorch版)代码实践 -深度学习基础-13Kaggle竞赛:2020加州房价预测

13Kaggle竞赛:2020加州房价预测 # 导入所需的库 import numpy as np import pandas as pd import torch import hashlib import os import tarfile import zipfile import requests from torch import nn from d2l import torch as d2l# 读取训练和测试数据 train_…

GIT回滚

1. 使用 git revert git revert 命令会创建一个新的提交,这个提交会撤销指定提交的更改。这通常用于公共分支(如 main 或 master),因为它不会重写历史。 git revert HEAD # 撤销最近的提交 # 或者指定一个特定的提交哈希值 …

【电子数据取证】如何快速在CSV中找到涉案手机号码

文章关键词:电子数据取证、聊天记录恢复、数据恢复、手机取证、介质取证 一、前言 在最近的取证工作中,我们遇到很多需要从大量的聊天记录数据中提取特定的信息,例如手机号码,银行号码,交易码。由于数据通常以数据库…

成熟制程新周期:华虹半导体股价飙升,大摩超配背后的逻辑是何?

半导体全线异动,新周期确定已到? 今年以来,在众多利好消息驱动下,华虹半导体(01347.HK)、中芯国际(00981.HK)、复旦微电(01385.HK)等港股芯片概念标的&#…

分享一个自己写的PC版的Ai指令保存工具

今天给大家分享下我用非常古老的VB写的一个小工具。纯粹是每次电脑使用指令太麻烦了,所以写了一个小工具。这个工具支持5条指令,作为一般的应该够用了。使用场景:比如你要经常使用指令,但是觉得复制指令麻烦,那么你可以…

Thinkphp校园新闻发布系统源码 毕业设计项目实例

Thinkphp校园新闻发布系统源码 毕业设计项目实例 校园新闻发布系统模块: 用户模块:注册,登陆,查看个人信息,修改个人信息,站内搜索,新闻浏览等功能, 后台管理员模块:会员…

月薪没到20K,必啃的WebGIS系统技术栈,你练到哪一步了?

WebGIS(网络地理信息系统)是目前地理信息系统(GIS)开发的主流,它利用互联网技术来发布、共享和交互地理空间数据。 一个完整的WebGIS项目通常涉及以下几个主要环节:具备一定的理论知识,数据生产…

Spring是如何设计IOC容器的?BeanFactory ApplicationContext

BeanFactory是Spring框架中最底层的接口,用于实例化、配置和管理bean。它使用控制反转(IOC)模式,将对象的创建、管理和装配的职责从应用程序代码中转移给Spring容器。这样,应用程序代码就无需关心对象如何创建和装配&a…

【区块链】POS(Proof of Stake)权益证明算法深度解析

🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 ​💫个人格言: "如无必要,勿增实体" 文章目录 POS(Proof of Stake)权益证明算法深度解析引言1. POS基本…

基于Matlab的细胞计数图像处理系统(GUI界面有报告) 【含Matlab源码 MX_003期】

简介: 本文旨在解决生物血细胞数目统计的挑战,提出了基于图像处理的综合方案。通过MATLAB平台,我们设计并实现了一套完整的细胞图像处理与分析流程。在预处理阶段,采用图像增强和阈值分割等方法,有效地提高了细胞图像的…

Linux---rpm/yum包管理器

文章目录 前言一、pandas是什么?二、使用步骤 1.引入库2.读入数据总结 一.RPM概述 RPM(Red Hat Package Manager)是Linux中的一种软件包管理格式也可以称为软件包管理器;它可以将软件包以二进制形式打包,并提供工具来安…

Conmi的正确答案——Vue默认加载方式设置为Yarn后怎么修改

Vue版本:3 1和2主要是搜索文件所在位置,Windows的这个文件一般在“C:\Users\{当前用户}”下,linux的非root情况下一般在“/home/{当前用户}”下。 1、打开“Everything”; 2、搜索“vuerc”; 3、打开“.vuerc”&#…

vue 和 js写屏幕自适应

实现屏幕自适应的方式有很多种,可以通过插件本身提供的方法,可以通过flex布局等,今天我们来写写通过js实现屏幕自适应。 以下是在vue中实现的屏幕自适应 首先在data中定义一下屏幕的默认大小和缩放比例 然后在mounted中获取窗口的内置宽高&a…

jrt从量变到质变

又是一个加班的周末,上周把台式机代码和数据库环境弄好了,这周进行大数据测试,直接把标本、标本医嘱、报告、报告结果、药敏结果等数据插入到1亿的规模,跑了一天一夜插入了5000多万个标本,后面接着补剩下的到一亿。 演…

生命在于学习——Python人工智能原理(3.5)

三、深度学习 9、常见神经网络 常见的神经网络有卷积神经网络(AlexNet、VGGNet)、循环神经网络(RNN) 长短时记忆网络(LSTM)。 (1)AlexNet AlexNet于2012年由Hinton学生Alex提出&a…