随着工程代码量的膨胀,我们将核心业务拆分成了多个独立的 HAR 和 HSP 模块。然而,在开发新版的交易链路时,传统的 router.pushUrl 暴露出了致命的缺陷。它不仅导致模块间产生了严重的循环依赖,在页面返回时,上一级页面往往无法精准感知数据的变化,导致状态脱节。为了解决这些问题,我们全面倒向了 Navigation 架构。

摒弃传统 Router 的全局解耦

早期的 router 是在全局维护一个页面栈,模块 A 跳转到模块 B,需要在代码里硬编码路径字符串。当模块 B 被重构时,模块 A 极其容易报错。Navigation 组件原生支持 NavPathStack,允许我们在底层创建一个独立的导航栈实例,并通过参数传递,彻底切断了跨模块路由的物理硬编码。

typescript

// 在主页面初始化导航栈
@Provide('pageStack') pageStack: NavPathStack = new NavPathStack();

Navigation(this.pageStack) {
  // 首页内容
}
.mode(NavigationMode.Stack)

通过 @Provide 注入的 pageStack,任何子模块只需要 @Consume 拿到这个实例,就能执行 pushPath 跳转,完全不需要知道目标页面属于哪个模块。

动态路由注册与拦截机制

Navigation 的强大之处在于其高度可定制的拦截器(Interceptor)。在复杂的交易链路中,用户必须登录才能进入结算页。传统做法是在每个页面加上繁琐的判断,现在只需在路由层统一拦截。

typescript

this.pageStack.setInterception({
  willShow: (from, to, operation, animated) => {
    // 核心拦截逻辑:判断目标页面是否需要登录
    if (to.pathInfo.name === 'CheckoutPage') {
      if (!AppStorage.get<boolean>('isLogin')) {
        // 警示:拦截跳转,重定向到登录页
        this.pageStack.pushPath({ name: 'LoginPage' });
        return false; 
      }
    }
    return true;
  }
});

执行这段拦截配置后,所有的鉴权逻辑都被收敛在了一个地方,页面本身只需要专注于 UI 渲染,代码清爽了不止一个量级。

返回栈的数据回传与生命周期对齐

router 时代,页面返回回传数据往往依赖于全局变量或事件总线。Navigation 提供了 NavPathStack 自带的参数传递机制。当在详情页完成操作后,可以通过 pop 方法携带参数返回。但这里有一个极其致命的警示:Navigation 的页面跳转异步性极强。必须合理利用 NavDestination 组件的 onShown 和 onHidden 生命周期,把数据刷新逻辑放在这里。综合而言,Navigation 不仅是一个 UI 容器,更是一套完整的路由状态管理方案。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐