当前位置: 首页 > news >正文

鸿蒙主流路由详解

鸿蒙主流路由详解

Navigation

第1页-1

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

Navigation官网地址

个人源码地址

路由跳转

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

统一写在主页面

  @BuilderPageMap(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()
第二步-定义页面跳转构造函数
  @BuilderPageMap(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的路由重定向到PageOnelet target: NavDestinationContext = to asNavDestinationContext;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的数据'})})}}
}

相关文章:

鸿蒙主流路由详解

鸿蒙主流路由详解 Navigation Navigation更适合于一次开发,多端部署,也是官方主流推荐的一种路由控制方式,但是,使用起来入侵耦合度高,所以,一般会使用HMRouter,这也是官方主流推荐的路由 Navigation官网地址 个人源码地址 路由跳转 第一步-定义路由栈 Provide(PageInfo) pag…...

C#构建一个简单的循环神经网络,模拟对话

循环神经网络&#xff08;Recurrent Neural Network, RNN&#xff09;是一种用于处理序列数据的神经网络模型。与传统的前馈神经网络不同&#xff0c;RNN具有内部记忆能力&#xff0c;可以捕捉到序列中元素之间的依赖关系。这种特性使得RNN在自然语言处理、语音识别、时间序列预…...

Linux上安装单机版Kibana6.8.1

1. 下载安装包 kibana-6.8.1-linux-x86_64.tar.gz 链接&#xff1a;https://pan.baidu.com/s/1b4kION9wFXIVHuWDn2J-Aw 提取码&#xff1a;rdrc 2. Kibana启动不能使用root用户&#xff0c;使用ES里创建的elsearch用户&#xff0c;进行赋权&#xff1a; chown -R elsearch:els…...

短视频矩阵矩阵,矩阵号策略

随着数字媒体的迅猛发展&#xff0c;短视频平台已经成为企业和个人品牌推广的核心渠道。在这一背景下&#xff0c;短视频矩阵营销策略应运而生&#xff0c;它通过高效整合和管理多个短视频账号&#xff0c;实现资源的最优配置和营销效果的最大化。本文旨在深入探讨短视频矩阵的…...

Rust 力扣 - 2266. 统计打字方案数

文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 这题可以先求按了多少次相同连续的按钮&#xff0c;所有的连续相同按钮表示的方案数的乘积就是本题答案 我们的关键问题就转换成了按n个连续相同按钮表示的方案数 设f(i)表示按i个连续相同按钮表示的方案数 如…...

【大数据技术与开发实训】携程景点在线评论分析

景点在线评论分析 题目要求实验目标技术实现数据采集获取所有相关景点页面的 URL获取所有相关景点对应的 poiId 及其他有用信息通过 poiId 获取所有景点的全部评论数据采集结果 数据预处理景点信息的数据预处理查看数据基本信息缺失值处理 用户评论的数据处理缺失值处理分词、去…...

46.坑王驾到第十期:vscode 无法使用 tsc 命令

点赞收藏加关注&#xff0c;你也能住大别墅&#xff01; 一、问题重现 上一篇帖子记录了我昨天在mac上安装typescript及调试的过程。今天打开vscode准备开干的时候&#xff0c;发现tsc命令又无法使用了&#xff0c;然后按照昨天的方法重新安装调试后又能用了&#xff0c;但是关…...

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

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

单片机_简单AI模型训练与部署__从0到0.9

IDE&#xff1a; CLion MCU&#xff1a; STM32F407VET6 一、导向 以求知为导向&#xff0c;从问题到寻求问题解决的方法&#xff0c;以兴趣驱动学习。 虽从0&#xff0c;但不到1&#xff0c;剩下的那一小步将由你迈出。本篇主要目的是体验完整的一次简单AI模型部署流程&#x…...

对撞双指针(七)三数之和

15. 三数之和 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请你返回所有和为 0 且不重复的三元组。 注意&#xff1a;答案中不可以包含重复的三元组…...

【Ubuntu24.04】服务部署(虚拟机)

目录 0 背景1 安装虚拟机1.1 下载虚拟机软件1.2 安装虚拟机软件1.2 安装虚拟电脑 2 配置虚拟机2.1 配置虚拟机网络及运行初始化脚本2.2 配置服务运行环境2.2.1 安装并配置JDK172.2.2 安装并配置MySQL8.42.2.3 安装并配置Redis 3 部署服务4 总结 0 背景 你的服务部署在了你的计算…...

timm库加载的模型可视化

在深度学习中&#xff0c;模型的可视化有助于了解模型的结构和层级关系。以下是几种方式来可视化使用 timm 库加载的模型&#xff1a; 打印模型结构 torch.nn.Module 的子类&#xff08;包括 timm 的模型&#xff09;可以通过 print() 查看其结构&#xff1a;import timm# 加…...

服务限流、降级、熔断-SpringCloud

本文所使用的组件&#xff1a;Nacos&#xff08;服务中心和注册中心&#xff09;、OpenFeign&#xff08;服务调用&#xff09;、Sentinel&#xff08;限流、降级&#xff09;、Hystrix&#xff08;熔断&#xff09; 项目结构&#xff1a; service-provider&#xff1a;提供服…...

2024最新YT-DLP使用demo网页端渲染

2024最新YT-DLP使用demo网页端渲染 前提摘要1.使用python的fastapi库和jinjia2库进行前端渲染2.代码实现1&#xff09;目录结构2&#xff09;代码style.cssindex.htmlresult.htmlmain.pyrun.py 3&#xff09;运行测试命令端运行 3.项目下载地址 前提摘要 2024最新python使用yt…...

《第十部分》1.STM32之通信接口《精讲》之IIC通信---介绍

经过近一周的USART学习&#xff0c;我深刻体会到通信对单片机的重要性。它就像人类的手脚和大脑&#xff0c;只有掌握了通信技术&#xff0c;单片机才能与外界交互&#xff0c;展现出丰富多彩的功能&#xff0c;变得更加强大和实用。 单片机最基础的“语言”是二进制。可惜&am…...

wireshark使用lua解析自定义协议

wireshark解析自定义协议 1.自定义的lua放入路径2.修改init.lua2.1 开启lua2.2 init.lua文件最后加入自己的lua文件位置&#xff0c;这里需要确保与自己的文件名相同 3.编写lua4.编写c抓包5.wireshark添加自定义协议如何加调试信息 1.自定义的lua放入路径 一般是自己软件的安装…...

(Keil)MDK-ARM各种优化选项详细说明、实际应用及拓展内容

参考 MDK-ARM各种优化选项详细说明、实际应用及拓展内容 本文围绕MDK-ARM优化选项,以及相关拓展知识(微库、实际应用、调试)进行讲述,希望对你今后开发项目有所帮助。 1 总述 我们所指的优化,主要两方面: 1.代码大小(Size) 2.代码性能(运行时间) 在MDK-ARM中,优…...

Qt实现可拖拽的矩形

之前项目上需要用Qt来绘制可拖拽改变形状的矩形。看了Qt Graphics相关的内容&#xff0c;虽然对Qt怎么添加图元的有了些了解&#xff0c;但是具体如何实现拖拽效果&#xff0c;一时也没有什么好的想法。还好网上有人分享的例子&#xff0c;很受启发。后来又回顾了一下这部分的代…...

CentOS:A服务器主动给B服务器推送(上传),B服务器下载A服务器文件(下载)

Linux:常识(bash: ip command not found )_bash: ip: command not found-CSDN博客 rsync 中断后先判断程序是否自动重连:ps aux | grep rsync 查看目录/文件是否被使用(查询线程占用):lsof /usr/local/bin/mongodump/.B_database1.6uRCTp 场景:MongoDB中集合非常大需要…...

Oracle 执行计划查看方法汇总及优劣对比

在 Oracle 数据库中&#xff0c;查看执行计划是优化 SQL 语句性能的重要工具。以下是几种常用的查看执行计划的方法及其优劣比较&#xff1a; 1. 使用 EXPLAIN PLAN FOR 和 DBMS_XPLAN.DISPLAY 方法 执行 EXPLAIN PLAN FOR 语句&#xff1a; EXPLAIN PLAN FOR SELECT * FROM …...

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M&#xff1a;百万&#xff08;Million&#xff09; B&#xff1a;十亿&#xff08;Billion&#xff09; 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的&#xff0c;但是一个参数所表示多少字节不一定&#xff0c;需要看这个参数以什么…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩

目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的Cloudfla…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

Spring AI与Spring Modulith核心技术解析

Spring AI核心架构解析 Spring AI&#xff08;https://spring.io/projects/spring-ai&#xff09;作为Spring生态中的AI集成框架&#xff0c;其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似&#xff0c;但特别为多语…...

Reasoning over Uncertain Text by Generative Large Language Models

https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

【生成模型】视频生成论文调研

工作清单 上游应用方向&#xff1a;控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看

文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...