鸿蒙主流路由详解

鸿蒙主流路由详解

Navigation

第1页-1

Navigation更适合于一次开发,多端部署,也是官方主流推荐的一种路由控制方式,但是,使用起来入侵耦合度高,所以,一般会使用HMRouter,这也是官方主流推荐的路由

Navigation官网地址

个人源码地址

路由跳转

第一步-定义路由栈
  @Provide('PageInfo') pageInfo: NavPathStack = new NavPathStack()
第二步-定义页面跳转构造函数

统一写在主页面

  @Builder
  PageMap(name: string) {
    if (name === "NavDestinationTitle1") {
      pageOneTmp() // 自定义组件
    } else if (name === "NavDestinationTitle2") {
      pageTwoTmp() // 自定义组件
    } else if (name === "NavDestinationTitle3") {
      pageThreeTmp() // 自定义组件
    }
  }

分开写在子页面

这种方法,需要自定义路由表,这也是跨包路由所必须的

路由表配置:

  1. 在跳转目标模块的配置文件module.json5添加路由表配置:

      {
        "module" : {
          "routerMap": "$profile:route_map"
        }
      }
    
  2. 添加完路由配置文件地址后,需要在工程resources/base/profile中创建route_map.json文件。添加如下配置信息:

      {
        "routerMap": [
          {
            "name": "PageOne", // 子组件名称
            "pageSourceFile": "src/main/ets/pages/PageOne.ets", // 子组件地址
            "buildFunction": "PageOneBuilder", // 字组件构造函数
            "data": {
              "description" : "this is PageOne" // 描述
            }
          }
        ]
      }
    
  3. 填写构造函数

    @Builder
    export function pageOneTmpBuilder(){
      pageOneTmp()
    }
    
第三步-进行页面跳转

这里只介绍常用简单的跳转方式

不带参数跳转

// 路由表在主页面
this.pageInfo.pushPathByName(`NavDestinationTitle${index}`, null) // 第一个参数是地址,第二个参数是数据
// 路由表是 router_map.json
this.pageInfo.pushPathByName('pageOneTmp', null) // 第一个参数是地址,第二个参数是数据

带参数跳转

// 路由表在主页面
let loginParam:LoginParam = new LoginParam("张三","男", 18) // LoginParam自定义类型
this.pageInfo.pushPathByName(`NavDestinationTitle${index}`,loginParam) // 第一个参数是地址,第二个参数是数据
// 路由表是 router_map.json
let loginParam:LoginParam = new LoginParam("张三","男", 18) // LoginParam自定义类型
this.pageInfo.pushPathByName(`pageOneTmp`,loginParam) // 第一个参数是地址,第二个参数是数据

参数解析

// 子页面
// 获得所有NavDestination的名称
let params:string[] = this.pageInfos.getAllPathName()
console.log(TAG,'所有页面名称',JSON.stringify(params))

// 通过Index获取参数
let obj = this.pageInfos.getParamByIndex(0) as LoginParam
console.log(TAG,'来源页面参数',JSON.stringify(obj))

// 通过名称获取参数(一般路由栈顶端的就是当前页面,params[params.length-1]可以路由栈栈顶名称)
let params2 = this.pageInfos.getParamByName(params[params.length-1])[0] as LoginParam
console.log(TAG,'来源页面参数',JSON.stringify(params2))

带参返回

// 子页面,可以放在onRead()方法里面接收,也可以放在aboutToAppear()方法里面接收
// 获得所有NavDestination的名称
let params:string[] = this.pageInfos.getAllPathName()
console.log(TAG,'所有页面名称',JSON.stringify(params))

// 通过Index获取参数
let obj = this.pageInfos.getParamByIndex(0) as LoginParam
console.log(TAG,'来源页面参数',JSON.stringify(obj))

// 通过名称获取参数(一般路由栈顶端的就是当前页面,params[params.length-1]可以路由栈栈顶名称)
let params2 = this.pageInfos.getParamByName(params[params.length-1])[0] as LoginParam
console.log(TAG,'来源页面参数',JSON.stringify(params2))
// 带参返回
this.pageInfos.pop(obj,true)

主页面解析子页面参数

// 解析参数
let loginParam:LoginParam = new LoginParam("张三","男", 18) // LoginParam自定义类型
this.pageInfo.pushPathByName(`NavDestinationTitle${index}`,loginParam,(popInfo)=>{
  console.log(TAG,`NavDestinationTitle${index}返回信息`,JSON.stringify(popInfo.result))
}) // 第一个参数是地址,第二个参数是数据,第三个处理子页面返回的参数

路由拦截

第一步-定义路由栈
  @Provide('PageInfo') pageInfo: NavPathStack = new NavPathStack()
第二步-定义页面跳转构造函数
  @Builder
  PageMap(name: string) {
    if (name === "NavDestinationTitle1") {
      pageOneTmp() // 自定义组件
    } else if (name === "NavDestinationTitle2") {
      pageTwoTmp() // 自定义组件
    } else if (name === "NavDestinationTitle3") {
      pageThreeTmp() // 自定义组件
    }
  }
第三步-进行页面跳转并进行拦截
// 解析参数
let loginParam: LoginParam = new LoginParam("张三", "男", 18) // LoginParam自定义类型
this.pageInfo.pushPathByName(`NavDestinationTitle${index}`, loginParam, (popInfo) => {
  console.log(TAG, `NavDestinationTitle${index}返回信息`, JSON.stringify(popInfo.result))
}) // 第一个参数是地址,第二个参数是数据,第三个处理子页面返回的参数

// 路由拦截
this.pageInfo.setInterception({
  willShow: (from: NavDestinationContext | "navBar", to:
  NavDestinationContext | "navBar",
    operation: NavigationOperation, animated: boolean) => {
    if (typeof to === "string") {
      console.log("target page is navigation home page.");
      return;
    }
    // 将跳转到PageTwo的路由重定向到PageOne
    let target: NavDestinationContext = to as
    NavDestinationContext;
    console.log(TAG, '当前要跳转界面', target.pathInfo.name)
    if (target.pathInfo.name === 'NavDestinationTitle1') {
      target.pathStack.pop();
      target.pathStack.pushPathByName('NavDestinationTitle2', null);
    }
  }
})

生命周期

第10页-7

对比

第13页-9

第13页-8

HmRouter

这种路由方式进行了解耦,不用再去写Build函数,它是基于自定义注解的方式,进行路由跳转,这也是官方推荐的方式

官网地址

个人源码地址

基础配置

第一步-使用ohpm安装依赖
ohpm install @hadss/hmrouter   // 路由框架
ohpm install @hadss/hmrouter-transitions   // 高阶转场动画库,依赖路由框架(可选)
第二步-拷贝artifacts到工程目录libs文件(需要自己创建)
第三步-修改oh-package.json5(entry目录切记)

报错的话重新输入路径

{
  "dependencies": {
    "@hadss/hmrouter": "file: ../libs/HMRouterLibrary-${version}.har",
    "@hadss/hmrouter-transitions": "file: ../libs/HMRouterTransitions-${version}.har"
  }
}
第四步-修改工程的hvigor/hvigor-config.json文件
{
  "dependencies": {
    "@hadss/hmrouter-plugin": "file: ../libs/hadss-hmrouter-plugin-${version}.tgz"
    // 使用npm仓版本号
  }
}
第五步-在模块中引入路由编译插件,修改 hvigorfile.ts
import { hapTasks } from '@ohos/hvigor-ohos-plugin';
import { hapPlugin } from '@hadss/hmrouter-plugin';
//管理HMRouter这个对象的,根据报的类型修改hapPlugin
export default {
    system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
    plugins:[hapPlugin()] /* Custom plugin to extend the functionality of Hvigor. */
}
第六步-可选配置hmrouter_config.json(自己在工程目录下创建)

插件扫描指定目录下的文件,动态的生成被包装好的页面对象

{
  "scanDir": ["src/main/ets/components","src/main/ets/interceptors"],
  "saveGeneratedFile": true
}
第七步-工程配置在工程目录下的build-profile.json5
"buildOption": {
    "strictMode": {
        "caseSensitiveCheck": true,
        "useNormalizedOHMUrl": true
    }
}

使用

第一步-初始化 onCreate()

在UIAbility或者启动框架AppStartup中初始化路由框架

export default class EntryAbility extends UIAbility {
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    HMRouterMgr.init({
      context: this.context
    })
  }
}
第二步-主界面

自定义主界面样式

/**
 * 自定义主界面样式
 */
class NavModifier extends AttributeUpdater<NavigationAttribute> {
  initializeModifier(instance: NavigationAttribute): void {
    instance.mode(NavigationMode.Stack);
    instance.navBarWidth('100%');
    instance.hideTitleBar(true);
    instance.hideToolBar(true);
  }
}

主界面使用

import { HMDefaultGlobalAnimator, HMNavigation } from '@hadss/hmrouter';
import { AttributeUpdater } from '@kit.ArkUI';

@Entry
@Component
struct Index {
  modifier: NavModifier = new NavModifier()

  build() {
    Column() {
      HMNavigation({
        navigationId:'mainNavigation',
        homePageUrl:'PageA', // 设置主页
        options:{
          standardAnimator:HMDefaultGlobalAnimator.STANDARD_ANIMATOR,
          dialogAnimator:HMDefaultGlobalAnimator.DIALOG_ANIMATOR,
          modifier:this.modifier // 设置页面风格
        }
      })
      {
        Button('点我')
      }
    }
    .height('100%')
    .width('100%')
  }
}

/**
 * 自定义主界面样式
 */
class NavModifier extends AttributeUpdater<NavigationAttribute> {
  initializeModifier(instance: NavigationAttribute): void {
    instance.mode(NavigationMode.Stack);
    instance.navBarWidth('100%');
    instance.hideTitleBar(true);
    instance.hideToolBar(true);
  }
}
第三步-可选配置拦截器
import { HMInterceptor, HMInterceptorAction, HMInterceptorInfo, IHMInterceptor } from "@hadss/hmrouter";

const TAG = '[JumpInfoInterceptor]'

@HMInterceptor({ interceptorName: 'JumpInfoInterceptor', global: true })
export class JumpInfoInterceptor implements IHMInterceptor {
  handle(info: HMInterceptorInfo): HMInterceptorAction {
    /**
     * export interface HMInterceptorInfo {
     * srcName: string;
     *  targetName?: string;
     *  isSrc?: boolean;
     *  type: HMActionType;
     *  routerPathInfo: HMRouterPathInfo;
     *  routerPathCallback?: HMRouterPathCallback;
     *  context: UIContext;
     * }
     * 可以根据自己的需求,配置拦截信息
     */
    let connectionInfo: string = info.type === 'push' ? 'jump to' : 'back to';
    console.info(TAG,'输出信息为',`${info.srcName} ${connectionInfo} ${info.targetName}`)
    return HMInterceptorAction.DO_NEXT;
  }
}
第四步-路由跳转

不带拦截器的跳转

import { HMRouter, HMRouterMgr } from '@hadss/hmrouter';

const TAG = '[PageC]'


@HMRouter({pageUrl:'PageC'})
@Component
export struct PageC {
  aboutToAppear(): void {
    let param = HMRouterMgr.getCurrentParam()
    console.log(TAG,'PageC的接收参数为',JSON.stringify(param))
  }

  build() {
    Column({space:20}){
      Button('PageC')
        .onClick(()=>{
          HMRouterMgr.pop({
            pageUrl:'PageC',
            param:'这是来自于C的数据'
          })
        })
    }
  }
}

带拦截器的跳转

import { HMRouter, HMRouterMgr } from "@hadss/hmrouter";

const TAG = '[PageB]'

@HMRouter({pageUrl:'PageB',interceptors:['JumpInfoInterceptor']})
@Component
export struct PageB {
  aboutToAppear(): void {
    let param = HMRouterMgr.getCurrentParam()
    console.log(TAG,'PageB的接收参数为',JSON.stringify(param))
  }

  build() {
    Column(){
      Button('PageB==>pop')
        .onClick(()=>{
          HMRouterMgr.pop({
            pageUrl:'PageA',
            param:'这是来自于B的数据'
          })
        })
      Button('PageB==>push')
        .onClick(()=>{
          HMRouterMgr.push({
            pageUrl:'PageC',
            param:'这是来自于B的数据'
          })
        })
    }
  }
}

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

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

相关文章

java使用itext生成pdf

一、利用Adobe Acrobat DC软件创建pdf模板 备好Adobe Acrobat DC软件 1.excel/jpg/png文件转pdf文件 右击打开我们要转换的文件 2.然后点击 添加 域 3.可以看到域的名字 4.调整字体大小/对齐方式等 5.保存 二&#xff0c;代码部分 首先 上依赖 <dependency><group…

生成对抗网络模拟缺失数据,辅助PAMAP2数据集仿真实验

PAMAP2数据集是一个包含丰富身体活动信息的数据集&#xff0c;它为我们提供了一个理想的平台来开发和测试HAR模型。本文将从数据集的基本介绍开始&#xff0c;逐步引导大家通过数据分割、预处理、模型训练&#xff0c;到最终的性能评估&#xff0c;在接下来的章节中&#xff0c…

全面解析:HTML页面的加载全过程(一)--输入URL地址,与服务器建立连接

用户输入URL地址&#xff0c;与服务器建立连接 用户在浏览器地址栏输入一个URL 浏览器开始执行以下三步操作操作&#xff1a;url解析、DNS查询、TCP连接 第一步&#xff1a;URL解析 什么是URL&#xff1f; URL(Uniform Resource Locator&#xff0c;统一资源定位符)是互联网…

STM32总体架构简单介绍

目录 一、引言 二、STM32的总体架构 1、三个被动单元 &#xff08;1&#xff09;内部SRAM &#xff08;2&#xff09;内部闪存存储器 &#xff08;3&#xff09;AHB到APB的桥&#xff08;AHB to APBx&#xff09; 2、四个主动&#xff08;驱动&#xff09;单元 &#x…

postman 调用 下载接口(download)使用默认名称(response.txt 或随机名称)

官网地址&#xff1a;https://www.postman.com 介绍 Postman 是一款流行的 API 开发和测试工具&#xff0c;用于发送 HTTP 请求、测试接口、调试服务器响应以及进行 API 文档管理。它支持多种请求类型&#xff08;如 GET、POST、PUT、DELETE 等&#xff09;&#xff0c;并且功能…

JavaScript将至

JS是什么&#xff1f; 是一种运行在客户端&#xff08;浏览器&#xff09;的编程语言&#xff0c;实现人机交互效果 作用捏&#xff1f; 网页特效 (监听用户的一些行为让网页作出对应的反馈) 表单验证 (针对表单数据的合法性进行判断) 数据交互 (获取后台的数据, 渲染到前…

Vue.js 学习总结(13)—— Vue3 version 计数介绍

前言 Vue3.5 提出了两个重要概念&#xff1a;version计数和双向链表&#xff0c;作为在内存和计算方面性能提升的最大功臣。既然都重要&#xff0c;那就单挑 version 计数来介绍&#xff0c;它在依赖追踪过程中&#xff0c;起到快速判断依赖项有没有更新的作用&#xff0c;所以…

全面解析多种mfc140u.dll丢失的解决方法,五种方法详细解决

当你满心期待地打开某个常用软件&#xff0c;却突然弹出一个错误框&#xff0c;提示“mfc140u.dll丢失”&#xff0c;那一刻&#xff0c;你的好心情可能瞬间消失。这种情况在很多电脑用户的使用过程中都可能出现。无论是游戏玩家还是办公族&#xff0c;面对这个问题都可能不知所…

《Spring 实战:小型项目开发初体验》

一、引言 Spring 作为一款强大的 Java 开发框架&#xff0c;在小型项目开发中有着广泛的应用。本文将带你深入体验 Spring 在小型项目开发中的实战过程&#xff0c;从环境搭建到项目部署&#xff0c;全面展示 Spring 的魅力。 一、引言 Spring 作为一款强大的 Java 开发框架&…

Altium Designer学习笔记 11-15 原理图的封装 编译 检查 _PCB封装库的创建

基于Altium Designer 23学习版&#xff0c;四层板智能小车PCB 更多AD学习笔记&#xff1a;Altium Designer学习笔记 1-5 工程创建_元件库创建Altium Designer学习笔记 6-10 异性元件库创建_原理图绘制 目录 11、Value值的核对 12、封装的统一管理 13、原理图的编译设置和检查…

【Spring Boot】# 使用@Scheduled注解无法执行定时任务

1. 前言 在 Spring Boot中&#xff0c;使用Scheduled注解来定义定时任务时&#xff0c;定时任务不执行&#xff1b;或未在规定时间执行。 import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component;Component public c…

Spring Boot3远程调用工具RestClient

Spring Boot3.2之后web模块提供了一个新的远程调用工具RestClient&#xff0c;它的使用比RestTemplate方便&#xff0c;开箱即用&#xff0c;不需要单独注入到容器之中&#xff0c;友好的rest风格调用。下面简单的介绍一下该工具的使用。 一、写几个rest风格测试接口 RestCont…

VLAN是什么,一个好的网络为什么要划分VLAN呢?

前言 在上一篇中讲解了交换机的工作原理&#xff0c;知道了交换机处理数据的转发方式&#xff0c;其中有两种情况会以广播方式进行发送数据&#xff0c;第一种是目的MAC是全F的&#xff0c;以及组播MAC&#xff0c;第二种是未知单播帧&#xff0c;那这个会带来什么样的问题呢&…

flowable流程图详细绘制教程

文章目录 前言一、flowable是什么&#xff1f;回答下之前的问题 二、flowable-modeler使用1. 使用步骤2.开始绘制弄一个请假的流程 三 加载该流程总结 前言 flowable有些晦涩难懂的东西&#xff1a; 我最开始接触的时候,还是用的activity,当时觉得好复杂,那么这次经过我自己在…

蓝桥杯c++算法秒杀【6】之动态规划【上】(数字三角形、砝码称重(背包问题)、括号序列、组合数问题:::非常典型的必刷例题!!!)

下将以括号序列、组合数问题超级吧难的题为例子讲解动态规划 别忘了请点个赞收藏关注支持一下博主喵&#xff01;&#xff01;&#xff01;! ! ! ! &#xff01; 关注博主&#xff0c;更多蓝桥杯nice题目静待更新:) 动态规划 一、数字三角形 【问题描述】 上图给出了一…

[Python3学习笔记-基础语法] Python3 基础语法

本篇文章详细介绍Python3的基础语法&#xff0c;主要包括编码、标识符、Python保留字、注释、行缩进、多行语句、Number类型、字符串、空行、print打印等。 这些是Python最基础的东西&#xff0c;掌握好了才能更好的学习后续的内容。 有兴趣共同结伴学习Python的朋友&#xff0…

HDR视频技术之三:色度学与颜色空间

HDR 技术的第二个理论基础是色度学。从前面的内容中可以了解到&#xff0c;光学以及人类视觉感知模型为人类提供了解释与分析人类感知亮度的理论基础&#xff0c;但是 HDR 技术不仅仅关注于提升图像与视频的亮度范围&#xff0c;同时也关注于提供更加丰富的色彩。因此&#xff…

数据库MYSQL——表的设计

文章目录 前言三大范式&#xff1a;几种实体间的关系&#xff1a;一对一关系&#xff1a;一对多关系&#xff1a;多对多关系&#xff1a; 前言 之前的博客中我们讲解的是关于数据库的增删改查与约束的基本操作&#xff0c; 是在已经创建数据库&#xff0c;表之上的操作。 在实…

C++自动化测试:GTest 与 GitLab CI/CD 的完美融合

在现代软件开发中&#xff0c;自动化测试是保证代码质量和稳定性的关键手段。对于C项目而言&#xff0c;自动化测试尤为重要&#xff0c;它能有效捕捉代码中的潜在缺陷&#xff0c;提高代码的可维护性和可靠性。本文将重点介绍如何在C项目中结合使用Google Test&#xff08;GTe…

备忘笔记-工具:JetBrains友好工具安装配置

1、配置/脚本文件下载 1、校验地址&#xff1a;https://3.jetbra.in/ 打开选择可用链接&#xff0c;点击跳转可用页面。 2、下载文件 左上角点击下载jetbra.zip文件 下载对应全家桶软件版本号&#xff0c;版本号在对应卡票右上角可见。 2、安装包下载 官网地址&#xff1a…