Navigation常见场景&解决方案
路由跳转场景
页面跳转是路由最常用的能力,Navigation通过NavPathStack提供了诸多方法,下文以pushDestination方法为例,介绍Navigation的路由跳转相关能力。
页面间跳转
NavPathStack提供了路由管理的能力,通过NavPathStack进行页面跳转,主要适用于页面较多的应用。
Step1:创建NavPathStack对象pageStack,通常使用@Provide进行修饰,方便后续子组件通过@Consumer获取,以实现子页面的路由跳转。也可以将pageStack传入路由框架,以实现路由框架开发(后续路由框架章节会介绍)的开发
@Entry
@Component
struct mainPageView {
[@Provide](/user/Provide)('pageStack') pageStack: NavPathStack = new NavPathStack()
...
build() {
...
}
}
Step2:构建路由表pageMap,该方法通过@Builder进行修饰,通过传入的pageName属性,返回不同页面。
@Entry
@Component
struct mainPageView {
[@Provide](/user/Provide)('pageStack') pageStack: NavPathStack = new NavPathStack()
[@Builder](/user/Builder)
PageMap(pageName: string) {
if (pageName === 'loginPage') {
loginPageView()
} else if (pageName === 'mainPage') {
mainPageView()
}
}
build() {
...
}
}
Step3:在build创建Navigation组件(需要传入pageStack参数),通过navDestination属性传入路由表pageMap,并通过pageStack.pushPath()实现页面跳转。
@Entry
@Component
struct mainPageView {
[@Provide](/user/Provide)('pageStack') pageStack: NavPathStack = new NavPathStack()
[@Builder](/user/Builder)
pageMap(pageName: string) {
if (pageName === 'loginPage') {
loginPageView()
} else if (pageName === 'mainPage') {
mainPageView()
}
}
build() {
Navigation(this.pageStack){
...
Button('login').onClick( ent => {
let pathInfo : NavPathInfo = new NavPathInfo('loginPage', null)
this.pageStack.pushDestination(pathInfo, true);
})
}.navDestination(this.pageMap)
...
}
}
页面间参数传递
Navigation的页面间,通过NavPathInfo对象中的params属性,实现从发起页到目标页的数据传递;通过onPop回调参数,实现处理目标页面的返回。
Step1:构建NavPathInfo对象,输入需要传递给目标页面的参数。params参数:将需要传递的数据封装起来进行传递。onPop参数:目标页面触发pop时的返回,在回调中通过PopInfo.info.param获取到返回的对象。
// 发起页 mainPage
let loginParam : LoginParam = new LoginParam()
// 构建pathInfo对象
let pathInfo : NavPathInfo = new NavPathInfo('loginPage', loginParam
, (popInfo: PopInfo) => {
let loginParam : LoginParam = popInfo.info.param as LoginParam;
...
})
this.pageStack.pushDestination(pathInfo, true);
// 讲参数传递到目标页
Step2:目标页面在NavDestination的onReady函数中,通过通过cxt.pathInfo.param,获取传递过来的参数。
build() {
NavDestination(){
...
}.hideTitleBar(true)
.onReady(cxt => {
this.loginParam = cxt.pathInfo.param as LoginParam;
...
})
}
Step3:目标页通过NavPathStack.pop方法返回起始页,其result参数用来传递需要返回给起始页的对象。
@Component
export struct loginPageView {
@Consume('pageInfo') pageStack : NavPathStack;
// 页面构建的对象
private loginParam! : LoginParam;
...
build() {
NavDestination(){
...
Button('login').onClick( ent => {
// 将对象返回给起始页
this.pageStack.pop(this.loginParam, true)
})
}
}
}
跨模块页面跳转
当应用模块较多,需要使用HSP(HAR)进行多模块开发,比如登录模块是一个独立团队开发,以HSP(HAR)的形式交付。此时主页应当从mainPage跳转到HSP(HAR)中的页面,需要先导入模块的自定义组件,将组件添加到pageMap中,再通过pushDestination进行跳转。
Step1:从HSP(HAR)中完成自定义组件(需要跳转的目标页面)开发,将自定义组件申明为export。
@Component
export struct loginPageInHSP {
@Consume('pageStack') pageStack: NavPathStack;
...
build() {
NavDestination() {
...
}
}
}
Step2:在HSP(HAR)的index.ets中导出组件。
export { loginPageInHSP } from "./src/main/ets/pages/loginPageInHSP"
Step3:配置好HSP(HAR)的项目依赖后,在mainPage中导入自定义组件,并添加到pageMap中,即可正常调用。
// 导入模块目标页自定义组件
import { loginPageInHSP } from 'library/src/main/ets/pages/loginPageInHSP'
@Entry
@Component
struct mainPage {
[@Provide](/user/Provide)('pageStack') pageStack: NavPathStack = new NavPathStack()
[@Builder](/user/Builder) pageMap(name: string) {
if (name === 'loginPageInHSP') {
// 路由到hsp包中的登录页面
loginPageInHSP()
}
}
build() {
Navigation(this.pageStack) {
Button("login With HSP module")
.onClick(() => {
let loginParam : LoginParamInHSP = new LoginParamInHSP()
let pathInfo : NavPathInfo = new NavPathInfo('loginPageInHSP', loginParam, (popInfo: PopInfo) => {})
this.pageStack.pushDestination(pathInfo, true);
})
}
.navDestination(this.pageMap)
}
}