【方舟UI框架】Navigation

Navigation 是路由导航的根视图容器,一般作为页面(@Entry)的根容器,包括单栏(Stack)、分栏(Split)和自适应(Auto)三种显示模式。一次开发,多端部署场景下,Navigation组件能够自动适配窗口显示大小,在窗口较大的场景下自动切换分栏展示效果。

TypeScript 复制代码
Navigation() {
  // ...
}
.mode(NavigationMode.Auto) // 自适应
.mode(NavigationMode.Split) // 分栏
.mode(NavigationMode.Stack) // 单栏

Navigation组件主要包含​导航页和子页。导航页由标题栏(包含菜单栏)、内容区和工具栏组成,可以通过hideNavBar属性进行隐藏,导航页不存在路由栈中,与子页,以及子页之间可以通过路由操作进行切换。在API version 9上,Navigation需要配合NavRouter组件实现页面路由。从API version 10开始,更推荐使用NavPathStack实现页面路由。

显示模式

自适应模式

Navigation组件默认为自适应模式,此时mode属性为NavigationMode.Auto。自适应模式下,当页面宽度大于等于一定阈值( API version 9及以前:520vp,API version 10及以后:600vp )时,Navigation组件采用分栏模式,反之采用单栏模式。

单页面模式

单页面模式适用于窄屏设备,发生路由跳转时,整个页面都会被替换。

分栏模式

分栏模式适用于宽屏设备 ,分为左右两部分,发生路由跳转时,只有右边子页会被替换

路由操作

Navigation路由相关的操作都是基于导航控制器 NavPathStack提供的方法进行,每个Navigation都需要创建并传入一个NavPathStack对象,用于管理页面。Navigation中的NavDestination页面存在于NavPathStack中,以栈的结构管理,称为路由栈。

TypeScript 复制代码
@Entry
@Component
struct Index {
  // 创建一个导航控制器对象并传入Navigation
  pageStack: NavPathStack = new NavPathStack();

  build() {
    Navigation(this.pageStack) {
    }
    .title('Main')
  }
}

页面跳转

NavPathStack通过Push相关的接口去实现页面跳转的功能,主要分为以下三类:

普通跳转

通过页面的name去跳转,并可以携带param。

TypeScript 复制代码
this.pageStack.pushPath({ name: "PageOne", param: "PageOne Param" });
this.pageStack.pushPathByName("PageOne", "PageOne Param");

带返回回调的跳转

跳转时添加onPop回调,能在页面出栈时获取返回信息,并进行处理。

TypeScript 复制代码
this.pageStack.pushPathByName('PageOne', "PageOne Param", (popInfo) => {
  console.log('Pop page name is: ' + popInfo.info.name + ', result: ' + JSON.stringify(popInfo.result));
});

带错误码的跳转

跳转结束会触发异步回调,返回错误码信息。

TypeScript 复制代码
this.pageStack.pushDestination({name: "PageOne", param: "PageOne Param"})
  .catch((error: BusinessError) => {
    console.error(`Push destination failed, error code = ${error.code}, error.message = ${error.message}.`);
  }).then(() => {
    console.info('Push destination succeed.');
  });
this.pageStack.pushDestinationByName("PageOne", "PageOne Param")
  .catch((error: BusinessError) => {
    console.error(`Push destination failed, error code = ${error.code}, error.message = ${error.message}.`);
  }).then(() => {
    console.info('Push destination succeed.');
  });

页面返回

NavPathStack通过Pop相关接口去实现页面返回功能。

TypeScript 复制代码
// 返回到上一页
this.pageStack.pop();
// 返回到上一个PageOne页面
this.pageStack.popToName("PageOne");
// 返回到索引为1的页面
this.pageStack.popToIndex(1);
// 返回到根首页(清除栈中所有页面)
this.pageStack.clear();

页面替换

NavPathStack通过Replace相关接口去实现页面替换功能。

TypeScript 复制代码
// 将栈顶页面替换为PageOne
this.pageStack.replacePath({ name: "PageOne", param: "PageOne Param" });
this.pageStack.replacePathByName("PageOne", "PageOne Param");
// 带错误码的替换,跳转结束会触发异步回调,返回错误码信息
this.pageStack.replaceDestination({name: "PageOne", param: "PageOne Param"})
  .catch((error: BusinessError) => {
    console.error(`Replace destination failed, error code = ${error.code}, error.message = ${error.message}.`);
  }).then(() => {
    console.info('Replace destination succeed.');
  })

页面删除

NavPathStack通过Remove相关接口去实现删除路由栈中特定页面的功能。

TypeScript 复制代码
// 删除栈中name为PageOne的所有页面
this.pageStack.removeByName("PageOne");
// 删除指定索引的页面
this.pageStack.removeByIndexes([1, 3, 5]);
// 删除指定id的页面
this.pageStack.removeByNavDestinationId("1");

移动页面

NavPathStack通过Move相关接口去实现移动路由栈中特定页面到栈顶的功能。

TypeScript 复制代码
// 移动栈中name为PageOne的页面到栈顶
this.pageStack.moveToTop("PageOne");
// 移动栈中索引为1的页面到栈顶
this.pageStack.moveIndexToTop(1);

参数获取

NavDestination子页第一次创建时会触发onReady回调,可以获取此页面对应的参数。

TypeScript 复制代码
@Component
struct Page01 {
  pathStack: NavPathStack | undefined = undefined;
  pageParam: string = '';

  build() {
    NavDestination() {
      // ...
    }.title('Page01')
    .onReady((context: NavDestinationContext) => {
      this.pathStack = context.pathStack;
      this.pageParam = context.pathInfo.param as string;
    })
  }
}

NavDestination组件中可以通过设置onResult接口,接收返回时传递的路由参数。

TypeScript 复制代码
class NavParam {
  desc: string = 'navigation-param'
}

@Component
struct DemoNavDestination {
  // ...
  build() {
    NavDestination() {
      // ...
    }
    .onResult((param: Object) => {
      if (param instanceof NavParam) {
        console.log('TestTag', 'get NavParam, its desc: ' + (param as NavParam).desc);
        return;
      }
      console.log('TestTag', 'param not instance of NavParam');
    })
  }
}

其他业务场景,可以通过主动调用NavPathStack的Get相关接口去获取指定页面的参数。

TypeScript 复制代码
// 获取栈中所有页面name集合
this.pageStack.getAllPathName();
// 获取索引为1的页面参数
this.pageStack.getParamByIndex(1);
// 获取PageOne页面的参数
this.pageStack.getParamByName("PageOne");
// 获取PageOne页面的索引集合
this.pageStack.getIndexByName("PageOne");

路由拦截

NavPathStack提供了setInterception方法,用于设置Navigation页面跳转拦截回调。该方法需要传入一个NavigationInterception对象,该对象包含三个回调函数:

无论是哪个回调,在进入回调时路由栈都已经发生了变化。

开发者可以在willShow回调中通过修改路由栈来实现路由拦截重定向的能力。

TypeScript 复制代码
this.pageStack.setInterception({
  willShow: (from: NavDestinationContext | "navBar", to: NavDestinationContext | "navBar",
    operation: NavigationOperation, animated: boolean) => {
    if (typeof to === "string") {
      console.log("target page is navigation home page.");
      return;
    }
    // 将跳转到PageTwo的路由重定向到PageOne
    let target: NavDestinationContext = to as NavDestinationContext;
    if (target.pathInfo.name === 'PageTwo') {
      target.pathStack.pop();
      target.pathStack.pushPathByName('PageOne', null);
    }
  }
})
相关推荐
@HNUSTer4 小时前
基于 HTML、CSS 和 JavaScript 的智能图像虚化系统
开发语言·前端·javascript·css·html
OEC小胖胖4 小时前
React学习之路永无止境:下一步,去向何方?
前端·javascript·学习·react.js·前端框架·react·web
啊啊啊啊8435 小时前
函数,数组与正则表达式
前端·chrome·正则表达式
YL有搞头7 小时前
VUE的模版渲染过程
前端·javascript·vue.js·面试·模版渲染
百思可瑞教育7 小时前
前端性能优化:请求和响应优化(HTTP缓存与CDN缓存)
前端·网络协议·http·缓存·性能优化·北京百思可瑞教育·百思可瑞教育
gnip11 小时前
文件操作利器:showOpenFilePicker
前端·javascript
繁依Fanyi11 小时前
做一个 3D 图片画廊
前端
繁依Fanyi12 小时前
用 Electron 做一个屏幕取色器
前端