# 如何监听Navigation路由的页面切换事件

#### 问题现象

如何监听Navigation的页面切换，以便在页面转场过程中执行自定义操作？如获取进退场页面的相关信息、拦截切换等。

#### 背景知识

*   @ohos.arkui.observer(无感监听)提供UI组件行为变化的无感监听能力。如页面生命周期、组件显隐状态、滚动事件等。其中uiObserver.on('navDestinationSwitch')可以监听Navigation的页面切换事件并执行自定义操作。
*   setInterception：用于设置Navigation页面跳转拦截回调。通过setInterception方法实现路由拦截，可用于统一处理页面跳转前的逻辑校验（如登录态验证、页面状态管理等）。

#### 解决方案

*   **方案一**：使用uiObserver.on('navDestinationSwitch')方法订阅Navigation页面切换事件，并在参数中传入回调函数，用于执行相应的逻辑处理。
    
    ```
    import { uiObserver } from '@kit.ArkUI';
    
    function callBackFunc(info: uiObserver.NavDestinationSwitchInfo) {
      let from = JSON.stringify(info.from);
      let to = JSON.stringify(info.to);
      console.info(`from:${from} to: ${to}`);
    }
    
    @Entry
    @Component
    struct NavObserverDemo {
      private stack: NavPathStack = new NavPathStack();
    
      @Builder
      Page() {
        PageOne();
      }
    
      aboutToAppear() {
        uiObserver.on('navDestinationSwitch', this.getUIContext(), callBackFunc); // 注册页面切换的监听
      }
    
      aboutToDisappear() {
        uiObserver.off('navDestinationSwitch', this.getUIContext(), callBackFunc);
      }
    
      build() {
        Navigation(this.stack) {
          Button('跳转').onClick(() => {
            this.stack.pushPath({ name: 'pageOne' });
          });
        }
        .title('Navigation')
        .navDestination(this.Page);
      }
    }
    
    @Component
    export struct PageOne {
      build() {
        NavDestination() {
          Text('pageOne');
        }.title('pageOne');
      }
    }
    ```
    
*   **方案二**：使用导航控制器NavPathStack的setInterception方法，在入参NavigationInterception中可以设置页面跳转前后的拦截回调。
    
    以跳转前拦截为例：在页面跳转前打印跳转目标页面的信息。
    
    ```
    @Entry
    @Component
    struct Index1 {
      pathStack: NavPathStack = new NavPathStack();
    
      aboutToAppear(): void {
        this.pathStack.setInterception({
          willShow: (from: NavDestinationContext | 'navBar', to: NavDestinationContext | 'navBar') => {
            if (typeof from === 'string') {
              let target = to as NavDestinationContext;
              console.info(`from page is navigation home -> ${target.pathInfo.name}`);
            } else if (typeof to === 'string') {
              let target = from as NavDestinationContext;
              console.info(`${target.pathInfo.name} -> to page is navigation home`);
            }
          }
        });
      }
    
      @Builder
      pageMap() {
        PageOne();
      }
    
      build() {
        Navigation(this.pathStack) {
          Column({ space: 30 }) {
            Text('PageOne');
            Button('跳转')
              .onClick(() => {
                this.pathStack.pushPathByName('PageOne', null, false);
              });
          };
        }.navDestination(this.pageMap);
      }
    }
    
    @Component
    struct PageOne {
      pathStack: NavPathStack = new NavPathStack();
    
      build() {
        NavDestination() {
          Column({ space: 30 }) {
            Text('PageOne');
            Button('跳转')
              .onClick(() => {
                this.pathStack.pop();
              });
          };
        }.title('PageOne')
        .onReady((context: NavDestinationContext) => {
          this.pathStack = context.pathStack;
        });
      }
    }
    ```
    

#### 常见FAQ

Q：无感监听有哪些常见事件？

A：监听滚动事件uiObserver.on('scrollEvent')、监听NavDestination组件的状态变化uiObserver.on('navDestinationUpdate')、监听TabContent页面的切换事件uiObserver.on('tabContentUpdate')等。