
HarmonyOS Next 优雅的路由跳转方案 ZRouter
HarmonyOS Next 优雅的路由跳转方案 ZRouter
前言
目前鸿蒙应用开发中,官方的路由跳转方案是
-
Router 不推荐 - Navigation 推荐
然后 HMRouter 和 ZRouter 都是基于 Navigation 做的封装。
介绍
ZRouter是一款轻量级且非侵入性的鸿蒙动态路由框架,目前在三方库上已有4,671 的下载量,也是鸿蒙生态中很流行的路由管理库。
也是 gitcode 上 G_Star 项目
ZRouter 已上架录入到华为鸿蒙生态伙伴组件专区
特性
ZRouter 具有以下优点:
- 简单易用
- 支持 V1 状态管理和 V2 状态管理;
- 支持 API 链式调用,让 API 更简洁直观;
- 支持 NavDestination 页面模板化
- 注解参数支持使用静态常量,可跨模块定义;
- 支持自定义与全局拦截器,可设优先级及中断逻辑,可实现页面重定向、登录验证等业务场景。
- 支持服务路由,可实现 Har/Hsp 模块间的通信;
- 支持全局及单个页面的生命周期函数管理,可使任意类都能享有与组件相同的生命周期特性,可实现页面埋点统计等业务场景;
- 支持跨多级页面参数携带返回监听;
- 支持自定义 URL 路径跳转,可在拦截器内自行解析 URL 实现业务逻辑;
- 内置多种转场动画效果(平移、旋转、渐变、缩放、高斯模糊),并支持自定义动画;
- 支持启动模式、混淆、嵌套 Navigation、Hap;
- 支持第三方 Navigation 的使用本库 API;
- 支持与您现有项目中的 Navigation 无缝融合,实现零成本向本库迁移;
- 支持 ArkUI-X 跨平台上使用;
- 未来计划:支持共享元素动画、持续优化
快速上手
1. 项目中配置router-register-plugin插件
// hvigor/hvigor-config.json5
"dependencies": {
"router-register-plugin":"1.3.2"
},
2. 在模块(har、hsp、hap 都可以)的 hvigorfile.ts 文件导入 router-register-plugin 插件,如在 Entry 中进行配置
// entry/hvigorfile.ts
import { hapTasks } from "@ohos/hvigor-ohos-plugin";
import { routerRegisterPlugin, PluginConfig } from "router-register-plugin";
// 2、初始化配置
const config: PluginConfig = {
scanDirs: ["src/main/ets/pages", "src/main/ets/views"], // 扫描的目录,如果不设置,默认是扫描src/main/ets目录
logEnabled: true, // 查看日志
viewNodeInfo: false, // 查看节点信息
isAutoDeleteHistoryFiles: true, // 删除无用编译产物
lifecycleObserverAttributeName: "xxx", // 可选,设置全局的生命周期实现类在组件上的属性名,默认值是lifecycleObserver
};
export default {
system: hapTasks /* Built-in plugin of Hvigor. It cannot be modified. */,
plugins: [routerRegisterPlugin(config)],
};
3. 在模块中,下载安装 ZRouter
ohpm install @hzw/zrouter
4. 在 EntryAbility 的 onCreate()方法中初始化 ZRouter
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
ZRouter.initialize((config) => {
// config.isLoggingEnabled = BuildProfile.DEBUG
config.isHSPModuleDependent = true
})
}
5. 将 page/Index.ets ,作为 ZRouter 的根容器,需要使用Navigation进行外层容器
import { Route, ZRouter } from '@hzw/zrouter'
@Entry
@Component
export struct Index {
build() {
// 获取NavPathStack实例对象
Navigation(ZRouter.getNavStack()){
Column({space:12}){
Button('跳转到登录').onClick((event: ClickEvent) => {
ZRouter.getInstance().push("Login")
})
}
}
.title('首页')
.height('100%')
.width('100%')
}
}
6. 其他页面需要使用@Route 和 NavDestination 进行修饰
// entry/src/main/ets/pages/Login.ets
import { Route, ZRouter } from "@hzw/zrouter";
@Route({ name: 'Login'})
@Component
export struct Login {
build() {
NavDestination(){
Column({space:12}){
Text("登录的页面")
// 返回使用pop方法
}
}
.title('登录')
.width('100%')
.height('100%')
}
}
7. 效果
启动页的设置流程
一般 app 的启动流程都是 启动页面->主页,这里因为使用了 pages/Index.ets 作为了根容器,所以当要实现启动页流程时,其实是需要用到 3 个页面。
1. page/Index.ets 作为页面根容器
// entry/src/main/ets/pages/Index.ets
import { Route, ZRouter } from '@hzw/zrouter'
@Route({ name: "Index" })
@Entry
@Component
export struct Index {
build() {
// 获取NavPathStack实例对象
Navigation(ZRouter.getNavStack()) {
Column({ space: 12 }) {
Button('跳转到登录').onClick((event: ClickEvent) => {
ZRouter.getInstance().push("Login")
})
}
}
.title('首页')
.height('100%')
.width('100%')
.onAppear(() => {
// 跳转启动页
ZRouter.getInstance().push("Splash")
})
.hideTitleBar(true)
}
}
2. 新建一个启动页 ,完成页面展示后,跳转到真正的业务首页
// entry/src/main/ets/pages/Splash.ets
import { Route, ZRouter } from "@hzw/zrouter";
@Route({ name: "Splash" })
@Component
export struct Splash {
build() {
NavDestination() {
Column() {
Button('Splash 启动页')
}
.width("100%")
.height("100%")
.justifyContent(FlexAlign.Center)
.backgroundColor(Color.Yellow)
}
.onAppear(() => {
// 模拟展示启动页
setTimeout(() => {
ZRouter.getInstance().navigation("Login")
}, 3000)
})
}
}
3. 业务首页
登录页面作为,业务中的首页
// entry/src/main/ets/pages/Login.ets
import { Route, TranslateAnimationOptions, ZRouter } from "@hzw/zrouter";
@Route({ name: 'Login' })
@Component
export struct Login {
build() {
NavDestination() {
Column({ space: 12 }) {
Text("登录的页面")
}
}
.title('登录')
.width('100%')
.height('100%')
}
}
4. 效果
动画转场
ZRouter 也提供了页面切换的动画效果,主要有:
- 平移
- 缩放
- 旋转
- 渐变
可以全局设置页面切换的动画,也可以单个页面设置。
全局动画
1. 在容器页面设置全局动画
import {
OpacityAnimateOptions,
RotateAnimateOptions,
Route,
ScaleAnimateOptions,
TranslateAnimationOptions,
ZRouter
} from '@hzw/zrouter'
@Entry
@Component
export struct Index {
build() {
// 获取NavPathStack实例对象
Navigation(ZRouter.getNavStack()) {
Column({ space: 12 }) {
Button('跳转到登录').onClick((event: ClickEvent) => {
ZRouter.getInstance().push("Login")
})
}
}
.title('首页')
.height('100%')
.width('100%')
.customNavContentTransition(
ZRouter.animateMgr()// 创建默认动画管理器
.defaultAnimateBuilder()// 设置进场动画参数
.setEnterAnimate({ duration: 500 })// 设置退场动画参数
.setExitAnimate({ duration: 700 })// 平移
// .addAnimateOptions(new TranslateAnimationOptions({ x: '50%', y: '50%' }))// 渐变
.addAnimateOptions(new OpacityAnimateOptions(0.01))// 缩放
// .addAnimateOptions(new ScaleAnimateOptions({ x: 0, y: 0 }))// 旋转
// .addAnimateOptions(new RotateAnimateOptions({ angle: 90 }))// 自定义转场动画回调
.getAnimCustomNavContentTransition())
}
}
2. 在子页面注册和卸载动画
比如,需要跳转到登录页面,那么就在登录页面注册和卸载动画
// entry/src/main/ets/pages/Login.ets
import { Route, ZRouter } from "@hzw/zrouter";
@Route({ name: 'Login' })
@Component
export struct Login {
build() {
NavDestination() {
Column({ space: 12 }) {
Text("登录的页面")
}
}
.title('登录')
.width('100%')
.height('100%')
.onReady((context: NavDestinationContext) => {
// 注册动画
ZRouter.animateMgr().registerAnimParam(this, context)
})
.onDisAppear(() => {
// 取消注册动画
ZRouter.animateMgr().unregisterAnim(this)
}) // 设置NavAnimationModifier
.attributeModifier(ZRouter.animateMgr().modifier(this))
}
}
3. 查看效果
单个页面动画
如果不想进行全局的页面跳转动画设置,可以给单个子页面进行设置,比如Login 页面
设置动画效果 和 注册、卸载动画函数
1. 容器页面
// entry/src/main/ets/pages/Index.ets
import {
OpacityAnimateOptions,
RotateAnimateOptions,
Route,
ScaleAnimateOptions,
TranslateAnimationOptions,
ZRouter
} from '@hzw/zrouter'
@Entry
@Component
export struct Index {
build() {
// 获取NavPathStack实例对象
Navigation(ZRouter.getNavStack()) {
Column({ space: 12 }) {
Button('跳转到登录').onClick((event: ClickEvent) => {
ZRouter.getInstance().push("Login")
})
}
}
.title('首页')
.height('100%')
.width('100%')
// 容器页面设置
.customNavContentTransition(
ZRouter
.animateMgr()
.getAnimCustomNavContentTransition())
}
}
2. 登录页面
// entry/src/main/ets/pages/Login.ets
import { Route, TranslateAnimationOptions, ZRouter } from "@hzw/zrouter";
@Route({ name: 'Login' })
@Component
export struct Login {
build() {
NavDestination() {
Column({ space: 12 }) {
Text("登录的页面")
}
}
.title('登录')
.width('100%')
.height('100%')
.onReady((context: NavDestinationContext) => {
ZRouter
.animateMgr()
.registerAnimParam(this, context)// 设置进场动画参数(比如动画时间,播放速度等)
.setEnterAnimate({ duration: 500, curve: Curve.LinearOutSlowIn })// 设置退场动画参数(比如动画时间,播放速度等)
.setExitAnimate({ duration: 500, curve: Curve.LinearOutSlowIn })// 添加平移动画
.addAnimateOptions(new TranslateAnimationOptions({ y: '100%' }))
})
.onDisAppear(() => {
// 取消注册动画
ZRouter.animateMgr().unregisterAnim(this)
}) // 设置NavAnimationModifier
.attributeModifier(ZRouter.animateMgr().modifier(this))
}
}
- 效果
生命周期
ZRouter 也提供了项目开发必备的生命周期
名称 | 解释 |
---|---|
aboutToAppear | 即将出现 |
aboutToDisappear | 即将消失 |
onWillAppear | 在即将出现时 |
onAppear | 在出现时 |
onWillShow | 在即将展示时 |
onShown | 在已展示时 |
onWillHide | 在即将隐藏时 |
onHidden | 在已隐藏时 |
onWillDisappear | 在即将消失时 |
onDisappear | 在消失时 |
ZRouter 中提供了3 种使用生命周期的方式,差别不大,分别是字面量和class的以及直接判断
字面量
在需要使用生命周期的页面中,进行注册生命周期
// entry/src/main/ets/pages/Index.ets:1
import { ILifecycleObserver, Lifecycle, LifecycleRegistry, Route, ZRouter } from '@hzw/zrouter'
@Route({ name: "Index" })
@Entry
@Component
export struct Index {
// 1 声明生命周期注册器
@Lifecycle lifecycle: LifecycleRegistry = LifecycleRegistry.create(this);
tag = "Index "
aboutToAppear(): void {
// 2、使用addObserver设置生命周期函数监听
let that = this
this.lifecycle.addObserver<ILifecycleObserver>({
aboutToAppear: () => {
console.log(`${that.tag}aboutToAppear`)
},
aboutToDisappear: () => {
console.log(`${that.tag}aboutToDisappear`)
},
onWillAppear(r) {
console.log(`${that.tag}onWillAppear`, r?.name, r?.navDestinationId)
},
onAppear(r) {
console.log(`${that.tag}onAppear`, r?.name, r?.navDestinationId)
},
onWillShow(r) {
console.log(`${that.tag}onWillShow `, r?.name, r?.navDestinationId)
},
onShown(r) {
console.log(`${that.tag}onShown `, r?.name, r?.navDestinationId)
},
onWillHide(r) {
console.log(`${that.tag}onWillHide `, r?.name, r?.navDestinationId)
},
onHidden(r) {
console.log(`${that.tag}onHidden `, r?.name, r?.navDestinationId)
},
onWillDisappear(r) {
console.log(`${that.tag}onWillDisappear `, r?.name, r?.navDestinationId)
},
onDisappear(r) {
console.log(`${that.tag}onDisappear `, r?.name, r?.navDestinationId)
}
})
}
build() {
// 获取NavPathStack实例对象
Navigation(ZRouter.getNavStack()) {
Column({ space: 12 }) {
Button('跳转到登录').onClick((event: ClickEvent) => {
ZRouter.getInstance().push("Login")
})
}
}
.title('首页')
.height('100%')
.width('100%')
}
}
class 的方式
- 用 class 的方式定义 class
// 1 定义生命周期class
@Observed
export class LifecycleModel implements ILifecycleObserver {
private tag = "class的生命周期: ";
loadState: string = "请求数据中...";
counter: number = 0;
aboutToAppear(): void {
console.log(this.tag + "aboutToAppear");
}
aboutToDisappear(): void {
console.log(this.tag + "aboutToDisappear");
}
onWillAppear(info: RouterInfo): void {
console.log(this.tag + "onWillAppear");
}
onAppear(info: RouterInfo): void {
console.log(this.tag + "onAppear");
// 模拟请求数据
setTimeout(() => {
this.counter = 100;
}, 3000);
}
onWillShow(info: RouterInfo): void {
console.log(this.tag + "onWillShow");
}
onShown(info: RouterInfo): void {
console.log(this.tag + "onShown");
}
onWillHide(info: RouterInfo): void {
console.log(this.tag + "onWillHide");
}
onHidden(info: RouterInfo): void {
console.log(this.tag + "onHidden");
}
onWillDisappear(info: RouterInfo): void {
console.log(this.tag + "onWillDisappear");
}
onDisappear(info: RouterInfo): void {
console.log(this.tag + "onDisappear");
}
}
- 在页面中使用
@Route({ name: "Index" })
@Entry
@Component
export struct Index {
// 2 使用生命周期class
@State viewModel: LifecycleModel = new LifecycleModel()
@Lifecycle lifecycle: LifecycleRegistry = LifecycleRegistry.create(this);
aboutToAppear(): void {
// 3 注册监听
this.lifecycle.addObserver(this.viewModel)
}
build() {
// 获取NavPathStack实例对象
Navigation(ZRouter.getNavStack()) {
Column({ space: 12 }) {
Button('跳转到登录').onClick((event: ClickEvent) => {
ZRouter.getInstance().push("Login")
})
}
}
.title('首页')
.height('100%')
.width('100%')
}
}
直接判断
通过 this.lifecycle.addListener 直接判断。
// entry/src/main/ets/pages/Index.ets:1
import { Lifecycle, LifecycleRegistry, Route, ZRouter } from '@hzw/zrouter'
@Route({ name: "Index" })
@Entry
@Component
export struct Index {
@Lifecycle lifecycle: LifecycleRegistry = LifecycleRegistry.create(this);
aboutToAppear(): void {
// 直接判定
this.lifecycle.addListener((pageName, r) => {
// pageName 生命周期函数的名字 aboutToAppear、onPageShow等
console.log('--2--', pageName, r?.name ?? "", r?.navDestinationId ?? "")
})
}
build() {
// 获取NavPathStack实例对象
Navigation(ZRouter.getNavStack()) {
Column({ space: 12 }) {
Button('跳转到登录').onClick((event: ClickEvent) => {
ZRouter.getInstance().push("Login")
})
}
}
.title('首页')
.height('100%')
.width('100%')
}
}
拦截器
ZRouter 支持多个拦截器和全局拦截器,在拦截器中可以做页面跳转的拦截,比如跳转前拦截、数据预取、登录拦截,404 拦截、埋点、自定义 URL 路径等等。
拦截器 | 解释 |
---|---|
onNavigateBefore | 在跳转之前回调 |
onRootWillShow | Navigation 根视图显示时回调 |
onPageWillShow | 页面显示时回调 |
onNavigate | 页面 push 或者 replace 跳转时回调 |
onShowCallback | 页面显示回调 |
常规使用
1. 定义拦截器 class
// entry/src/main/ets/utils/GlobalNavigateInterceptor.ets
import {
IGlobalNavigateInterceptor,
DestinationInfo,
InterceptorInfo,
ZRouter,
RedirectType,
} from "@hzw/zrouter";
import { promptAction } from "@kit.ArkUI";
export class GlobalNavigateInterceptor implements IGlobalNavigateInterceptor {
static count = 0;
/**
* 在跳转之前回调,可以在此回调中拦截跳转做一些自定义的逻辑,比如修改路由参数、数据预取、拦截跳转、拦截登录等场景
* @param dest
* @returns DestinationInfo#action 为NavigationAction.BLOCK 则表示拦截跳转,NEXT继续执行
* @note
* 如果通过ZRouter.getNavStack().push()方法跳转,则不会回调此方法,后续会考虑兼容
* 只有通过ZRouter.getInstance().push()方法跳转时会回调此方法
*/
onNavigateBefore: (destInfo: DestinationInfo) => Promise<DestinationInfo> = (
destInfo
) => {
console.log("IInterceptor Global onNavigateBefore -> ", destInfo.name);
return new Promise((resolve, _) => {
// 拦截页面1
if (destInfo.name === "Login") {
console.log("拦截了登录页面");
// 拦截跳转到Login页面
if (GlobalNavigateInterceptor.count === 0) {
// 自己定义的一些逻辑
destInfo.param = " 在拦截器onNavigateBefore中已替换参数 ";
destInfo.next(); // 继续跳转 默认的 ,可以不写
}
}
resolve(destInfo);
});
};
/**
* Navigation根视图显示时回调
* @param fromContext
*/
onRootWillShow: ((fromContext: NavDestinationContext) => void) | undefined = (
fromContext
) => {
console.log(
"IInterceptor Global onRootWillShow: ",
fromContext.pathInfo.name
);
};
/**
* 页面显示时回调,当fromContext、toContext是一样时,则在NavBar根页面中启动的
* @param fromContext
* @param toContext
*/
onPageWillShow:
| ((
fromContext: NavDestinationContext,
toContext: NavDestinationContext
) => void)
| undefined = (from, to) => {
console.log(
"IInterceptor Global onPageWillShow: ",
from,
to.pathInfo.name,
to.pathInfo.param
);
};
/**
* 页面push 或者 replace跳转时回调
* @param context
*/
onNavigate: ((context: InterceptorInfo) => void) | undefined = (info) => {
if (info.notRegistered) {
return;
}
console.log("IInterceptor Global onNavigate -> ", info.name);
let isLogin = AppStorage.get<boolean>("isLogin");
if (info.isNeedLogin && !isLogin) {
let param = info.param;
ZRouter.getInstance()
.setParam(param)
.setAnimate(true)
.setPopListener((result) => {
if (result.data) {
// 登录成功
promptAction.showToast({ message: `登录成功` });
return true; // 返回true 则继续跳转登录前的页面
} else {
return false;
}
})
.redirect("LoginPage", RedirectType.REPLACE);
}
};
/**
* 页面显示回调,鸿蒙sdk默认的,没有处理逻辑,如果其他的回调函数无法满足你的需求,可考虑在这里实现
* @param context
*/
onShowCallback: InterceptionShowCallback = (info) => {};
}
2. 注册使用
// entry/src/main/ets/pages/Index.ets:1
import { Route, ZRouter } from '@hzw/zrouter'
import { GlobalNavigateInterceptor } from '../utils/GlobalNavigateInterceptor';
@Route({ name: "Index" })
@Entry
@Component
export struct Index {
aboutToAppear(): void {
// 添加拦截器
ZRouter.setGlobalInterceptor(new GlobalNavigateInterceptor());
}
build() {
// 获取NavPathStack实例对象
Navigation(ZRouter.getNavStack()) {
Column({ space: 12 }) {
Button('跳转到登录').onClick((event: ClickEvent) => {
// 此时会触发拦截器
ZRouter.getInstance().push("Login")
})
}
}
.title('首页')
.height('100%')
.width('100%')
}
}
needLogin
普通的页面在使用装饰器 @Route 的时候,也可以传递一个属性needlogin:boolean
,该属性会在拦截器中出现,我们可以结合该属性进行登录的权限校验。
1. 页面中使用
然后当跳转到这个页面时,拦截器中的就可以获取到该属性
ZRouter.getInstance().push("Cart")
2. 拦截器中处理
携带参数跳转
跳转页面的时候携带参数的写法比较简单
1. 携带参数跳转 setParam
// entry/src/main/ets/pages/Index.ets:1
import { Route, ZRouter } from '@hzw/zrouter'
export interface IGoods {
num: number
name: string
}
@Route({ name: "Index" })
@Entry
@Component
export struct Index {
build() {
// 获取NavPathStack实例对象
Navigation(ZRouter.getNavStack()) {
Column({ space: 12 }) {
Button('跳转到登录').onClick((event: ClickEvent) => {
// ZRouter.getInstance().push("Login")
ZRouter.getInstance()
.setParam({ num: 100, name: "手机" })
.push("Login")
})
}
}
.title('首页')
.height('100%')
.width('100%')
}
}
2. 获取页面参数 getParam
// entry/src/main/ets/pages/Login.ets
import { Route, TranslateAnimationOptions, ZRouter } from "@hzw/zrouter";
import { IGoods } from "./Index";
@Route({ name: 'Login' })
@Component
export struct Login {
build() {
NavDestination() {
Column({ space: 12 }) {
Text("登录的页面")
}
}
.title('登录')
.width('100%')
.height('100%')
.onReady((context: NavDestinationContext) => {
const param = ZRouter.getInstance().getParam() as IGoods
console.log("参数", param.num, param.name)
})
}
}
跨模块跳转
这里演示两个模块,一个是hap-entry,另外一个是hsp-library,演示entry跳转到 library 模块。
1. 项目中新建 hsp 模块-library
2. library 模块下载 ZRouter library/oh-package.json5
"dependencies": {
"@hzw/zrouter": "^1.4.1",
}
3. library模块在 hvigorfile.ts
导入 router-register-plugin
// library/hvigorfile.ts
import { hspTasks } from "@ohos/hvigor-ohos-plugin";
import { routerRegisterPlugin, PluginConfig } from "router-register-plugin";
// 2、初始化配置
const config: PluginConfig = {
scanDirs: ["src/main/ets/pages", "src/main/ets/views"], // 扫描的目录,如果不设置,默认是扫描src/main/ets目录
logEnabled: true, // 查看日志
viewNodeInfo: false, // 查看节点信息
isAutoDeleteHistoryFiles: true, // 删除无用编译产物
lifecycleObserverAttributeName: "xxx", // 可选,设置全局的生命周期实现类在组件上的属性名,默认值是lifecycleObserver
};
export default {
system: hspTasks /* Built-in plugin of Hvigor. It cannot be modified. */,
plugins: [
routerRegisterPlugin(config),
] /* Custom plugin to extend the functionality of Hvigor. */,
};
4. library模块新建 Info 页面
// library/src/main/ets/pages/Info.ets
import { Route } from "@hzw/zrouter"
@Route({ name: "Info" })
@Component
export struct Info {
build() {
NavDestination() {
Column() {
Button('Info')
}
.width("100%")
.height("100%")
.justifyContent(FlexAlign.Center)
}
}
}
5. entry 模块引入其他模块 entry/oh-package.json5
"dependencies": {
"@hzw/zrouter": "^1.4.1",
"library": "file:../library"
},
6. 进行页面跳转
// entry/src/main/ets/pages/Index.ets:1
import { Route, ZRouter } from '@hzw/zrouter'
import { GlobalNavigateInterceptor } from '../utils/GlobalNavigateInterceptor';
export interface I13 {
id: number;
name: string
}
@Route({ name: "Index" })
@Entry
@Component
export struct Index {
aboutToAppear(): void {
// 添加拦截器
ZRouter.setGlobalInterceptor(new GlobalNavigateInterceptor());
}
build() {
// 获取NavPathStack实例对象
Navigation(ZRouter.getNavStack()) {
Column({ space: 12 }) {
Button('跳转到登录').onClick((event: ClickEvent) => {
ZRouter.getInstance().push("Login")
})
Button('跳转到购物车').onClick((event: ClickEvent) => {
ZRouter.getInstance().push("Cart")
})
Button("跳转到商品详情页面")
.onClick(() => {
ZRouter.getInstance().setParam({
id: 1,
name: "商品1"
})
.push("Goods")
})
Button('跳转到信息详情页面').onClick((event: ClickEvent) => {
ZRouter.getInstance().push("Info")
})
}
}
.title('首页')
.height('100%')
.width('100%')
}
}
7. 效果
NavDestination 页面模板化能力
页面模板能力可以让我们不需要每一个页面都添加 NavNavigation 组件,提高我们的开发效率。
在@Route 注解中使用 useTemplate 即可使用页面模板化能力,如:
import { Route } from "@hzw/zrouter"
@Route({ name: "Demo", useTemplate: true, title: "DemoTitle" })
@Component
export struct Demo {
build() {
Column() {
Button('Demo')
}
.width("100%")
.height("100%")
.justifyContent(FlexAlign.Center)
}
}
接口列表
- ZRouter: 是路由管理器,包括了初始化、路由操作、服务路由、生命周期、拦截器、模板化、动画等功能的管理
- NavDestBuilder: 路由的进出栈管理,主要包括跳转、返回、替换、移除等操作。
ZRouter 类接口
方法名 | 描述 | 参数 | 返回值 | 废弃状态 |
---|---|---|---|---|
initialize |
初始化路由,可传入一个配置函数 | invoke?: ((config: ConfigInitializer) => void) |
void |
否 |
setModuleLoadedListener |
设置模块加载完成的监听器,在使用了服务路由会生效 | listener: () => void |
void |
否 |
isDynamicLoadedComplete |
判断模块是否动态加载完成 | 无 | boolean |
否 |
getInstance |
获取路由操作的实例,用于进行跳转、返回等操作 | stackName: string = DEFAULT_STACK_NAME |
NavDestBuilder<ObjectOrNull> |
否 |
addService |
添加服务路由,外部不需要手动调用,会在编译阶段自动注册 | name: string , service: IProvider |
void |
否 |
getService |
获取服务路由管理类 | name: string |
T extends IProvider null |
否 |
animateMgr |
获取动画管理类 | 无 | NavAnimationMgr |
否 |
registerNavStack |
注册路由栈 | stackName: string = DEFAULT_STACK_NAME , pathStack: NavPathStack |
void |
否 |
unregisterNavStack |
解除注册路由栈 | stackName: string |
void |
否 |
getNavStack |
获取默认栈名的路由栈 | willShow?: InterceptionShowCallback |
NavPathStack |
否 |
getNavStackByName |
根据栈名获取路由栈,通常用不上 | stackName: string |
NavPathStack |
否 |
getCurrentNavStack |
获取当前路由栈实例 | 无 | NavPathStack |
否 |
getLastNavDestinationId |
获取当前路由栈的栈顶页面 DestinationId |
无 | string or undefined |
否 |
setGlobalInterceptor |
设置全局拦截器 | interceptor: IGlobalNavigateInterceptor , stackName: string = DEFAULT_STACK_NAME |
void |
否 |
setInterceptor |
添加拦截器 | interceptor: T extends IInterceptor , stackName: string = DEFAULT_STACK_NAME |
void |
否 |
removeInterceptor |
移除拦截器 | interceptor: T extends IInterceptor , stackName: string = DEFAULT_STACK_NAME |
boolean |
否 |
addGlobalLifecycleObserver |
添加全局的 NavDestination 页面的生命周期观察者 |
observer: IL extends ILifecycleObserver |
未明确 | 否 |
addLifecycleObserver |
添加单个 NavDestination 页面的生命周期观察者 |
observer: LifecycleObserver |
未明确 | 否 |
templateMgr |
获取 NavDestination 页面模板管理器,通常用不上 |
无 | TemplateMgr |
否 |
getCurrentStackName |
获取当前路由栈名称 | 无 | string |
否 |
getParamByKey |
获取路由参数,建议带上默认值和泛型 | key: string , defVal: ObjectOrNull = null |
P = ObjectOrNull |
否 |
NavDestBuilder 类接口
方法名 | 描述 | 参数 | 返回值 | 废弃状态 |
---|---|---|---|---|
setAnimate |
设置是否启动动画 | animated: boolean |
NavDestBuilder<T> |
否 |
setLaunchMode |
设置启动模式,api12 起才会生效 | mode: LaunchMode |
NavDestBuilder<T> |
否 |
setParam |
设置页面跳转携带的参数,通过getParam 获取参数 |
param: ObjectOrNull |
NavDestBuilder<T> |
否 |
withParam |
设置页面跳转携带的参数,key-value 形式,建议使用,通过ZRouter.getParamByKey(key) 获取参数 |
key: string , value: ObjectOrNull |
NavDestBuilder<T> |
否 |
setPopListener |
监听页面返回携带的结果,所有页面返回结果都会回调着 | callback: OnPopResultCallback<TObjectOrNull> |
NavDestBuilder<T> |
否 |
总结
ZRouter 作为鸿蒙生态中流行的路由管理库,为 HarmonyOS Next 应用提供了简洁而强大的路由解决方案。它的主要优势包括:
-
简单易用:ZRouter 提供链式 API 调用,使代码更简洁直观,降低开发者的使用门槛。
-
丰富的动画效果:内置多种转场动画(平移、旋转、渐变、缩放等),并支持自定义,使页面切换更加流畅美观。
-
强大的拦截器机制:可实现页面重定向、登录验证、埋点统计等复杂业务场景。
-
完善的生命周期管理:提供丰富的生命周期函数,让任意类都能享有与组件相同的生命周期特性。
-
跨模块通信能力:支持服务路由,实现 Har/Hsp 模块间的无缝通信。
-
页面模板化:通过@Route 注解和 useTemplate 配置,提高开发效率和代码复用率。
-
兼容性和可扩展性:支持与现有 Navigation 无缝融合,实现零成本迁移;适用于 ArkUI-X 跨平台开发。
ZRouter 的设计思路遵循简洁、高效、可扩展的原则,为鸿蒙应用开发者提供了一套完整的路由解决方案,极大地简化了页面跳转、参数传递和页面生命周期管理的复杂性,是构建大型 HarmonyOS 应用的理想选择。
更多推荐
所有评论(0)