Navigation的进阶知识与拦截器配置

发布于:2025-03-10 ⋅ 阅读:(19) ⋅ 点赞:(0)

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.效果展示

img

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. 拦截逻辑流程图解

image-20250309205538032

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)
  }

网站公告

今日签到

点亮在社区的每一天
去签到