【鸿蒙ArkUI路由/导航系列】十:Navigation嵌套开发

1、Navigation嵌套开发简介

Navigation作为导航框架,支持嵌套使用。如下示例场景:

  • 外层Navigation A通过栈操作push了一系列NavDestination,其中一个NavDestination内部又嵌套了一个Navigation B,并且该Navigation B也具有自己的NavPathStack,也可以在内部进行路由跳转。

通过上述逻辑可以将业务逻辑划分成不同的模块,应用主体逻辑模块只负责在不同的子业务之间进行路由,而各个子业务之间可以通过自己内部的Navigation,实现内部页面的路由。

下面通过实现一个应用集成不同小程序的demo来阐述Navigation嵌套场景的用法。

2、案例分享

2.1 主页逻辑模块

主页中有一个Navigation用于不同小程序模块之间的路由跳转

// src/main/ets/pages/Index.ets
@Component
struct HomePage {
  private stack: NavPathStack | undefined = undefined;
  build() {
    NavDestination() {
      Column() {
        // 跳转到购物小程序
        Stack({alignContent: Alignment.Center}) {
          Text('购物小程序').fontSize(25).fontColor(Color.White)
        }.onClick(() => {
          this.stack?.pushPath({name: "shopping"})
        }).width(200).height(90).borderRadius(40).backgroundColor('#fff3bb3f')
        // 跳转到外卖小程序
        Stack({alignContent: Alignment.Center}) {
          Text('外卖小程序').fontSize(25).fontColor(Color.White)
        }.onClick(() => {
          this.stack?.pushPath({name: "takeout"})
        }).width(200).height(90).borderRadius(40).backgroundColor('#fff3bb3f')
        // 跳转到打车小程序
        Stack({alignContent: Alignment.Center}) {
          Text('打车小程序').fontSize(25).fontColor(Color.White)
        }.onClick(() => {
          this.stack?.pushPath({name: "taxi"})
        }).width(200).height(90).borderRadius(40).backgroundColor('#fff3bb3f')
      }.width('100%').height('100%').justifyContent(FlexAlign.SpaceEvenly)
    }.width('100%').height('100%')
    .onReady((ctx: NavDestinationContext) => {
      this.stack = ctx?.pathStack;
    })
  }
}
@Builder
export function HomePageBuilder() {
  HomePage()
}
@Entry
@Component
struct Index {
  private stack: NavPathStack = new NavPathStack();
  aboutToAppear(): void {
    this.stack.pushPath({name: 'home'})
  }
  build() {
    Navigation(this.stack) {
    }
    .hideNavBar(true)
    .mode(NavigationMode.Stack)
    .height('100%')
    .width('100%')
  }
}

2.2 购物小程序模块

购物小程序页面内有一个嵌套的Navigation用于不同子页面之间的路由跳转

// src/main/ets/pages/Shopping.ets
import { InnerControl } from './Common';
@Component
struct ShoppingPage {
  private stack: NavPathStack = new NavPathStack();
  build() {
    NavDestination() {
      Column() {
        // 在该NavDestination内部嵌套了一个Navigation,并且使用一个单独的导航控制器,用于购物小程序内部的路由
        Navigation(this.stack) {
          InnerControl().height('100%').width('100%')
        }.height('100%').width('100%')
        .backgroundColor('#fff8dbdb')
        .mode(NavigationMode.Stack)
      }.width('100%').height('100%')
    }.width('100%').height('100%')
    .title('购物').hideBackButton(true)
  }
}
@Builder
export function ShoppingBuilder() {
  ShoppingPage()
}

2.3 外卖小程序模块

外卖小程序页面内有一个嵌套的Navigation用于不同子页面之间的路由跳转

// src/main/ets/pages/Takeout.ets
import { InnerControl } from './Common';
@Component
struct Takeout {
  private stack: NavPathStack = new NavPathStack();
  build() {
    NavDestination() {
      Column() {
        // 在该NavDestination内部嵌套了一个Navigation,并且使用一个单独的导航控制器,用于外卖小程序内部的路由
        Navigation(this.stack) {
          InnerControl().height('100%').width('100%')
        }.height('100%').width('100%')
        .backgroundColor('#ffe7f8db')
        .mode(NavigationMode.Stack)
      }.width('100%').height('100%')
    }.width('100%').height('100%')
    .title('外卖').hideBackButton(true)
  }
}
@Builder
export function TakeoutBuilder() {
  Takeout()
}

2.4 打车小程序模块

打车小程序页面内有一个嵌套的Navigation用于不同子页面之间的路由跳转

// src/main/ets/pages/Taxi.ets
import { InnerControl } from './Common';
@Component
struct Taxi {
  private stack: NavPathStack = new NavPathStack();
  build() {
    NavDestination() {
      Column() {
        // 在该NavDestination内部嵌套了一个Navigation,并且使用一个单独的导航控制器,用于打车小程序内部的路由
        Navigation(this.stack) {
          InnerControl().height('100%').width('100%')
        }.height('100%').width('100%')
        .backgroundColor('#ffc3f9fc')
        .mode(NavigationMode.Stack)
      }.width('100%').height('100%')
    }.width('100%').height('100%')
    .title('打车').hideBackButton(true)
  }
}
@Builder
export function TaxiBuilder() {
  Taxi()
}

2.5 小程序内部页面模块

// src/main/ets/pages/Common.ets
@Component
export struct InnerControl {
  private stack: NavPathStack | undefined = undefined;
  aboutToAppear(): void {
    let info = this.queryNavigationInfo();
    this.stack = info?.pathStack;
  }
  build() {
    Column() {
      Button('内部业务A').onClick(() => {
        this.stack?.pushPath({name: "detailA"})
      }).width(150).height(60).borderRadius(20).backgroundColor('#fff3bb3f')
      Button('内部业务A').onClick(() => {
        this.stack?.pushPath({name: "detailB"})
      }).width(150).height(60).borderRadius(20).backgroundColor('#fff3bb3f')
    }.width('100%').height('100%').justifyContent(FlexAlign.SpaceEvenly)
  }
}
@Component
export struct DetailA {
  build() {
    NavDestination() {
      InnerControl().width('100%').height('100%')
    }.width('100%').height('100%').backgroundColor('#fff6c5c5')
  }
}
@Builder
export function DetailABuilder() {
  DetailA()
}
@Component
export struct DetailB {
  build() {
    NavDestination() {
      InnerControl().width('100%').height('100%')
    }.width('100%').height('100%').backgroundColor('#ffddfaae')
  }
}
@Builder
export function DetailBBuilder() {
  DetailB()
}

上述demo效果如下图所示:

3、附件

上述案例完整示例代码如下: (代码链接待补充)

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值