Harmony开发之页面路由与导航——应用的中枢神经

引入:多页面应用的路由管理需求

在真实应用开发中,几乎所有的应用都需要多个页面来组织功能。比如电商应用需要首页、商品详情页、购物车、个人中心等页面;社交应用需要聊天列表、聊天窗口、设置等页面。如何优雅地管理这些页面之间的跳转、参数传递和返回逻辑,就成为了应用架构的核心问题。HarmonyOS提供了两种主要的路由方案:Router模块和Navigation组件,它们共同构成了应用的中枢神经系统。

一、Router模块基础使用

核心概念

Router模块是HarmonyOS最初提供的页面路由方案,通过URL进行页面跳转和管理。虽然在新版本中推荐使用Navigation组件,但了解Router仍很重要,特别是在维护现有项目时。

基本页面跳转

// 文件:pages/Index.ets
import { router } from '@kit.ArkUI';

@Entry
@Component
struct Index {
  build() {
    Column() {
      Button('跳转到详情页')
        .onClick(() => {
          // 使用pushUrl保留当前页面
          this.getUIContext().getRouter().pushUrl({
            url: 'pages/DetailPage'
          }, router.RouterMode.Standard, (err) => {
            if (err) {
              console.error(`跳转失败: ${err.code}, ${err.message}`);
              return;
            }
            console.info('跳转成功');
          })
        })
        
      Button('替换当前页面')
        .onClick(() => {
          // 使用replaceUrl替换当前页面
          this.getUIContext().getRouter().replaceUrl({
            url: 'pages/LoginPage'
          })
        })
    }
  }
}

两种跳转模式对比

Router模块提供两种跳转模式和两种实例模式:

跳转模式 特点 适用场景
pushUrl 保留当前页,压入页面栈 需要返回的页面跳转
replaceUrl 替换当前页,销毁当前页 登录后跳转,不需要返回
// Single模式示例:确保页面唯一性
this.getUIContext().getRouter().pushUrl({
  url: 'pages/SettingsPage'
}, router.RouterMode.Single)

二、Navigation组件推荐方案

为什么选择Navigation

Navigation组件相比Router模块具有更丰富的动效、更好的多端部署能力和更灵活的栈操作。从API Version 10开始,推荐使用NavPathStack实现页面路由。

基本架构搭建

// 文件:pages/Index.ets - 主页面
@Entry
@Component
struct MainPage {
  pageStack: NavPathStack = new NavPathStack()
  
  @Builder
  pageMap(name: string) {
    if (name === 'ProductDetail') {
      ProductDetailPage()
    } else if (name === 'ShoppingCart') {
      ShoppingCartPage()
    }
  }
  
  build() {
    Navigation(this.pageStack) {
      Column() {
        List() {
          ListItem() {
            Text('商品列表项')
              .onClick(() => {
                // 跳转到商品详情页
                this.pageStack.pushPath({ name: 'ProductDetail', param: { id: '123' } })
              })
          }
        }
      }
    }
    .title('商品列表')
    .mode(NavigationMode.Stack)
    .navDestination(this.pageMap)
  }
}

子页面配置

// 文件:pages/ProductDetail.ets
@Component
export struct ProductDetailPage {
  pathStack: NavPathStack = new NavPathStack()
  @State productInfo: string = ''
  
  build() {
    NavDestination() {
      Column() {
        Text(this.productInfo)
          .fontSize(20)
        Button('加入购物车')
          .onClick(() => {
            this.pathStack.pushPath({ name: 'ShoppingCart' })
          })
        Button('返回')
          .onClick(() => {
            this.pathStack.pop()
          })
      }
    }
    .title('商品详情')
    .onReady((context: NavDestinationContext) => {
      this.pathStack = context.pathStack
      // 获取传递的参数
      const params = context.pathInfo.param as Record<string, string>
      this.productInfo = `商品ID: ${params.id}`
    })
  }
}

三、参数传递与接收

Router方式的参数传递

// 发送参数
this.getUIContext().getRouter().pushUrl({
  url: 'pages/DetailPage',
  params: {
    productId: '12345',
    productName: 'HarmonyOS开发指南',
    price: 99.9
  }
})

// 接收参数(在目标页面)
@Entry
@Component
struct DetailPage {
  @State productId: string = ''
  @State productName: string = ''
  
  onPageShow() {
    const params = this.getUIContext().getRouter().getParams() as Record<string, any>
    this.productId = params.productId as string
    this.productName = params.productName as string
  }
  
  build() {
    // 页面内容
  }
}
// 发送参数
this.pageStack.pushPath({ 
  name: 'ProductDetail', 
  param: { 
    id: '123', 
    title: '商品标题',
    price: 199.9
  } 
})

// 接收参数
@Component
struct ProductDetailPage {
  @State productData: object = {}
  
  build() {
    NavDestination() {
      // 页面内容
    }
    .onReady((context: NavDestinationContext) => {
      this.productData = context.pathInfo.param as object
    })
  }
}

四、返回逻辑与结果传递

基本返回操作

// Router方式返回
this.getUIContext().getRouter().back() // 简单返回
this.getUIContext().getRouter().back({
  url: 'pages/IndexPage'
}) // 返回到指定页面

// Navigation方式返回
this.pathStack.pop() // 返回上一页
this.pathStack.popToIndex(0) // 返回到首页
this.pathStack.clear() // 清空栈返回到根页面

带结果返回

// 在详情页返回时传递结果
this.getUIContext().getRouter().back({
  url: 'pages/IndexPage',
  params: {
    operationResult: 'success',
    message: '商品已成功购买'
  }
})

// 在主页面接收返回结果
@Entry
@Component
struct IndexPage {
  @State resultMessage: string = ''
  
  onPageShow() {
    const params = this.getUIContext().getRouter().getParams() as Record<string, string>
    if (params && params.operationResult) {
      this.resultMessage = params.message
      // 显示结果提示
    }
  }
}

五、路由配置与最佳实践

路由表配置

对于Navigation组件,需要在工程配置中设置路由表:

// 文件:resources/base/profile/route_map.json
{
  "routerMap": [
    {
      "name": "ProductDetail",
      "pageSourceFile": "src/main/ets/pages/ProductDetail.ets",
      "buildFunction": "ProductDetailBuilder"
    },
    {
      "name": "ShoppingCart", 
      "pageSourceFile": "src/main/ets/pages/ShoppingCart.ets",
      "buildFunction": "ShoppingCartBuilder"
    }
  ]
}
// 在module.json5中配置
{
  "module": {
    "pages": "$profile:main_pages",
    "routerMap": "$profile:route_map"
  }
}

生命周期管理

@Entry
@Component
struct ProductDetailPage {
  onPageShow() {
    console.info('页面显示:商品详情页')
    // 页面显示时的初始化操作
  }
  
  onPageHide() {
    console.info('页面隐藏:商品详情页')
    // 页面隐藏时的清理操作
  }
  
  onBackPress() {
    console.info('返回按钮被点击')
    // 返回true表示自定义返回逻辑,false使用默认逻辑
    return false
  }
  
  build() {
    // 页面内容
  }
}

六、高级特性与性能优化

路由拦截器

// 添加路由前置守卫
router.addBeforeHook(() => {
  if (!this.isUserLoggedIn()) {
    this.showLoginDialog()
    return false // 拦截跳转
  }
  return true // 允许跳转
})

动态路由与懒加载

对于大型项目,可以使用动态路由实现模块解耦和按需加载:

// 动态导入页面组件
this.pageStack.pushPath({ 
  name: 'LazyPage',
  param: { module: 'advanced' }
})

// 配置动态路由表
@Builder
pageMap(name: string) {
  if (name === 'LazyPage') {
    // 动态导入,实现懒加载
    DynamicImport('lazy-module/src/main/ets/pages/LazyPage')
  }
}

总结

Router模块和Navigation组件共同构成了HarmonyOS应用的路由神经系统。Router模块适合简单的页面跳转场景,而Navigation组件提供了更强大、更灵活的路由管理能力,特别适合复杂的多页面应用。

行动建议

  • 新项目优先选择Navigation组件,享受更丰富的功能和更好的性能
  • 合理使用参数传递机制,保持页面间数据传递的简洁性
  • 注意页面栈的管理,避免栈深度过大导致内存问题
  • 对于需要登录验证的页面,使用路由拦截器统一处理权限校验
  • 大型项目考虑使用动态路由实现模块化解耦

通过合理运用路由与导航机制,可以构建出结构清晰、用户体验良好的多页面HarmonyOS应用。

posted @ 2025-12-24 10:31  wrystart  阅读(3)  评论(0)    收藏  举报