HarmonyOS鸿蒙NEXT中Navigation的进阶知识与拦截器配置

HarmonyOS鸿蒙NEXT中Navigation的进阶知识与拦截器配置 Navigation的进阶知识与拦截器配置

  • 写得不是很详细,后续有时间会补充,建议参考官方文档食用

1. 如何配置路由信息

1.1 创建工程结构

src/main/ets
├── pages
   └── navigation
       ├── views
          ├── Mine.ets      // 个人中心页
          ├── Login.ets     // 登录页
          └── ErrorPage.ets // 错误页
       └── NavagationIndex.ets // 导航入口
├── routerMap.json5           // 路由配置文件

1.2 核心路由配置解析(routerMap.json5)

{
  "routerMap": [
    {
      "name": "mine",       // 路由唯一标识符
      "buildFunction": "MineBuilder",   
      "pageSourceFile": "src/main/.../Mine.ets" 
    },
    // ...其他路由项
  ]
}

关键字段含义

关键字段 说明
name 路由标识符,用于编程式导航
buildFunction 页面构建器函数名(关联组件注册)
pageSourceFile 源代码文件位置(动态加载基础)

1.3 案例演示

1. 创建首页面
@Entry
@Component
struct TextPage {
  @Provide
  navPathStack:NavPathStack = new NavPathStack()
  build() {
  Navigation(this.navPathStack){
    Text('这是首页')
      Button('跳到下一页去')
      .onClick(()=>{
        this.navPathStack.pushPath({name:'nextOne'})
      })
  }
  }
}
2. 创建子页面(跳转页面)
@Builder
function PageOne() {
  TextPage_()
}

@Component
struct TextPage_ {
  @Consume
  navPathStack: NavPathStack

  build() {
    NavDestination() {
      Text('这是我从首页面跳过来的第一个页面')
      Image($r('app.media.Cover'))
        .width(100)
        .aspectRatio(1)
      Button('跳到第三个页面去')
        .onClick(() => {
          this.navPathStack.pushPath({ name: 'pageTwo' })
        })
    }
  }
}

@Builder
function PageTwo() {
  TextPage2_()
}

@Component
struct TextPage2_ {
  build() {
    NavDestination() {
      Text('这是我从首页面跳过来的第二个页面')
      Image($r('app.media.Cover2'))
        .width(100)
        .aspectRatio(1)
    }

  }
}
3. 配置json.map映射路径
{
      "name": "nextOne",
      "buildFunction": "PageOne",
      "pageSourceFile": "src/main/ets/pages/TextPage_.ets"
    },
    {
      "name": "pageTwo",
      "buildFunction": "PageTwo",
      "pageSourceFile": "src/main/ets/pages/TextPage_.ets"
    }
4. 效果展示

2. 导航入口组件实现(NavagationIndex.ets)

1. 组件结构

@Entry
@Component
struct NavagationIndex {
  @Provide 
  navPathStack: NavPathStack = new NavPathStack()
  
  build() {
    Navigation(this.navPathStack) {
      // 初始页面内容
      Button('跳转至-我的').onClick(()=>{
        this.navPathStack.pushPath({name: 'mine'})
      })
    }
    .mode(NavigationMode.Auto) // 跨设备适配
  }
}

2. 导航模式说明

模式 适用场景
NavigationMode.Stack 单页面栈模式(移动端)
NavigationMode.Split 分栏模式(平板/PC)
NavigationMode.Auto 自动适配设备

3. 拦截器配置

1. 拦截器注册时机

.onAppear(() => {
  this.registerInterceptors()
})

2. 拦截逻辑流程图解

3. 关键拦截逻辑代码

const token = AppStorage.get('token')! as string || '';
if (t.pathInfo?.name === 'mine' && token === '') {
  // 拦截动作分解
  t.pathStack.pop();          // 移除无效跳转
  t.pathStack.pushPath({      // 重定向到登录页
    name: "login"
  });
}

4. 错误处理机制

if (!t.pathInfo && f.pathInfo.name !== 'error') {
  f.pathStack.pushPath({name: 'error'}) // 注入错误页
  return;
}

5. 代码示例

import { promptAction } from '@kit.ArkUI'

@Entry
@Component
struct NavagationIndex {
  @Provide
  navPathStack: NavPathStack = new NavPathStack()

  registerInterceptors() {
    this.navPathStack.setInterception({
      //f从哪来,t到哪去
      willShow: (f, t) => {
        if (typeof t === 'string'||typeof f ==='string') {
          return
        }
        //f可能是首页跳过来的
        //必须加个逻辑与
        // if(!t.pathInfo && f.pathInfo.name !='error'){
        //   f.pathStack.pushPath({name:'error'})
        //   return
        //   //返回不好返回
        // }

        if (t.pathInfo.name === 'mine') {
          promptAction.showToast({
            message: '拦截到我要去mine'
          })
          //拦截你 不让你跳
          // t.pathStack.pop()
          const token = AppStorage.get('token')! as string || ''
          //拦截!!!
          if (token === '') {
            t.pathStack.pop()
            //去登录
            t.pathStack.pushPath({
              name: "login"
            })
          }
          return
        }

      },
      //t 跳转之后的拦截
      didShow: () => {

      }
    })
  }
  build() {
    Navigation(this.navPathStack) {
      //还没有进行跳转,但是已经有展示的内容了
      Text('这是我的首页')
      Button('跳转至-我的')
        .onClick(() => {
          this.navPathStack.pushPath({
            name: 'mine'
          })
        })
    }
    .onAppear(() => {
      this.registerInterceptors()
    })
    .height('100%')
    .width('100%')
    //跨设备
    .mode(NavigationMode.Auto)
  }
2 回复

在HarmonyOS NEXT中,Navigation组件用于管理页面间的导航和跳转。Navigation的进阶知识包括路由配置、页面栈管理以及拦截器配置。

  1. 路由配置:在鸿蒙中,路由配置通过router模块实现。开发者可以在config.json中定义路由规则,指定页面的路径和对应的组件。例如:
{
  "pages": [
    {
      "name": "MainPage",
      "path": "/main"
    },
    {
      "name": "DetailPage",
      "path": "/detail"
    }
  ]
}

通过router.pushrouter.replace方法,可以在代码中实现页面跳转。

  1. 页面栈管理:Navigation组件维护了一个页面栈,记录了用户访问的页面顺序。开发者可以通过router.back方法返回上一个页面,或者使用router.clear清空页面栈。

  2. 拦截器配置:拦截器用于在页面跳转前后执行特定逻辑。鸿蒙提供了router.beforeEachrouter.afterEach两个钩子函数。beforeEach在跳转前执行,可用于权限验证或页面跳转拦截;afterEach在跳转后执行,可用于日志记录或页面加载完成后的操作。

例如,使用beforeEach进行权限验证:

router.beforeEach((to, from, next) => {
  if (to.path === '/detail' && !hasPermission()) {
    next('/main');
  } else {
    next();
  }
});

使用afterEach进行日志记录:

router.afterEach((to, from) => {
  console.log(`Navigated from ${from.path} to ${to.path}`);
});

通过合理配置路由、管理页面栈和使用拦截器,开发者可以更好地控制页面导航流程,提升应用的用户体验。

更多关于HarmonyOS鸿蒙NEXT中Navigation的进阶知识与拦截器配置的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙NEXT中,Navigation组件用于管理页面导航,支持多种导航模式和拦截器配置。进阶知识包括:

  1. 导航模式:支持栈式导航、标签导航和抽屉导航,开发者可根据需求选择合适的模式。

  2. 拦截器配置:通过NavigationInterceptor接口实现导航拦截,可在页面跳转前进行权限验证、数据预加载等操作。例如:

NavigationInterceptor interceptor = new NavigationInterceptor() {
    @Override
    public boolean onIntercept(NavigationRequest request) {
        // 拦截逻辑
        return false; // 返回true表示拦截,false表示放行
    }
};
Navigation.addInterceptor(interceptor);
  1. 动态路由:支持动态注册和注销路由,灵活应对复杂业务场景。

  2. 生命周期管理:Navigation组件与页面生命周期紧密关联,确保资源合理释放。

通过合理配置拦截器和掌握进阶知识,可提升应用导航的灵活性和安全性。

回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!