Skip to content

0x014-鸿蒙应用开发笔记3-导航

示例-静态路由

可以使用pushPath、pushPathByName等方式跳转

  • this.pageInfos.pushPath({ name: "xxx" })
  • this.pageInfos.pushPathByName("xxx")
js
@Entry  
@Component  
struct Index {  
  // 创建一个页面栈对象 
  pageInfos: NavPathStack = new NavPathStack()   
  
  @Builder  
  PageMap(name: string) {  
    if (name === 'NtPage') {  
      NtPage()  
    }  
  }  
  
  build() {  
    // 初始化必须传入页面栈对象 
    Navigation(this.pageInfos) {  
      Button() {  
        Text("Go Next")  
          .padding(12)  
          .foregroundColor(Color.White)  
      }  
      .onClick(() => {  
        this.pageInfos.pushPath({ name: "NtPage" })  
      })  
    }  
    .mode(NavigationMode.Stack)   
    .navDestination(this.PageMap)   
    .title("Main")   
    .height('100%')  
    .width('100%')  
    .backgroundColor('#F1F3F5')  
  }  
}  
  
@Component  
export struct NtPage {  
  build() {  
    NavDestination() {   
      Column() {  
        Text("hi~")  
      }.width('100%').height('100%')  
    }.title("NavDestinationTitle3")   
}
@Entry  
@Component  
struct Index {  
  // 创建一个页面栈对象 
  pageInfos: NavPathStack = new NavPathStack()   
  
  @Builder  
  PageMap(name: string) {  
    if (name === 'NtPage') {  
      NtPage()  
    }  
  }  
  
  build() {  
    // 初始化必须传入页面栈对象 
    Navigation(this.pageInfos) {  
      Button() {  
        Text("Go Next")  
          .padding(12)  
          .foregroundColor(Color.White)  
      }  
      .onClick(() => {  
        this.pageInfos.pushPath({ name: "NtPage" })  
      })  
    }  
    .mode(NavigationMode.Stack)   
    .navDestination(this.PageMap)   
    .title("Main")   
    .height('100%')  
    .width('100%')  
    .backgroundColor('#F1F3F5')  
  }  
}  
  
@Component  
export struct NtPage {  
  build() {  
    NavDestination() {   
      Column() {  
        Text("hi~")  
      }.width('100%').height('100%')  
    }.title("NavDestinationTitle3")   
}

示例-动态路由

增加routerMap配置和文件:

json
// module.json5
{  
 ...
  "module": {  
    "routerMap": "$profile:router_map", 
  }
  ...
}
// module.json5
{  
 ...
  "module": {  
    "routerMap": "$profile:router_map", 
  }
  ...
}

router_map.json文件:

name跳转页面名称。
pageSourceFile跳转目标页在包内的路径,相对src目录的相对路径。
buildFunction跳转目标页的入口函数名称,必须以@Builder修饰。
data应用自定义字段。可以通过配置项读取接口getConfigInRouteMap获取。
json
{  
  "routerMap": [  
    {  
      // 跳转页面名称
      "name": "NextPage",  
      // 跳转目标页在包内的路径,相对src目录的相对路径
      "pageSourceFile": "src/main/ets/pages/NextPage.ets",  
      // 跳转目标页的入口函数名称,必须以@Builder修饰。
      "buildFunction": "NextPageBuilder",  
      "data": {  
        "description": "this is Detail"  
      }  
    }  
  ]  
}
{  
  "routerMap": [  
    {  
      // 跳转页面名称
      "name": "NextPage",  
      // 跳转目标页在包内的路径,相对src目录的相对路径
      "pageSourceFile": "src/main/ets/pages/NextPage.ets",  
      // 跳转目标页的入口函数名称,必须以@Builder修饰。
      "buildFunction": "NextPageBuilder",  
      "data": {  
        "description": "this is Detail"  
      }  
    }  
  ]  
}

页面跳转代码(可以删除.navDestination相关的代码):

js
@Entry 
@Component
struct Index {
  // 创建一个页面栈对象并传入Navigation 
  pageInfos: NavPathStack = new NavPathStack() 

  //@Builder 
  //PageMap(name: string) { 
  //  if (name === 'NtPage') { 
  //    NtPage() 
  //  } 
  //}

  build() {
    // 初始化必须携带参数
    Navigation(this.pageInfos) {
      Button() {
        Text("Go Next")
          .padding(12)
          .foregroundColor(Color.White)
      }
      .onClick(() => {
        this.pageInfos.pushPath({ name: "NextPage" }) 
      })
    }
    .mode(NavigationMode.Stack) 
    //.navDestination(this.PageMap) 
    .title("Main")
    .height('100%')
    .width('100%')
    .backgroundColor('#F1F3F5')
  }
}
@Entry 
@Component
struct Index {
  // 创建一个页面栈对象并传入Navigation 
  pageInfos: NavPathStack = new NavPathStack() 

  //@Builder 
  //PageMap(name: string) { 
  //  if (name === 'NtPage') { 
  //    NtPage() 
  //  } 
  //}

  build() {
    // 初始化必须携带参数
    Navigation(this.pageInfos) {
      Button() {
        Text("Go Next")
          .padding(12)
          .foregroundColor(Color.White)
      }
      .onClick(() => {
        this.pageInfos.pushPath({ name: "NextPage" }) 
      })
    }
    .mode(NavigationMode.Stack) 
    //.navDestination(this.PageMap) 
    .title("Main")
    .height('100%')
    .width('100%')
    .backgroundColor('#F1F3F5')
  }
}

跳转的子页面:

js
@Entry
@Component
struct NextPage {
  build() {
    NavDestination() { 
      Text(this.message)
        .id('NextPageHelloWorld')
        .fontSize(50)        
    }
    .title('Detail') 
  }
}

@Builder 
export function NextPageBuilder() { 
  NextPage() 
} 
@Entry
@Component
struct NextPage {
  build() {
    NavDestination() { 
      Text(this.message)
        .id('NextPageHelloWorld')
        .fontSize(50)        
    }
    .title('Detail') 
  }
}

@Builder 
export function NextPageBuilder() { 
  NextPage() 
} 

示例-参数传入并获取

页面1:

js
@Entry
@Component
struct Index {
  @State message: string = 'Hello World';
  pageInfos: NavPathStack = new NavPathStack()

  build() {
    Navigation(this.pageInfos) {
      Button() {
        Text("Go Next")
          .padding(12)
          .foregroundColor(Color.White)
      }
      .onClick(() => {
        const record: Record<string, string> = { 'foo': 'bar' };  
        this.pageInfos.pushPath({ name: "NextPage", param: record })  
      })
    }
    .mode(NavigationMode.Stack)
    .title("Main")
    .height('100%')
    .width('100%')
    .backgroundColor('#F1F3F5')
  }
}
@Entry
@Component
struct Index {
  @State message: string = 'Hello World';
  pageInfos: NavPathStack = new NavPathStack()

  build() {
    Navigation(this.pageInfos) {
      Button() {
        Text("Go Next")
          .padding(12)
          .foregroundColor(Color.White)
      }
      .onClick(() => {
        const record: Record<string, string> = { 'foo': 'bar' };  
        this.pageInfos.pushPath({ name: "NextPage", param: record })  
      })
    }
    .mode(NavigationMode.Stack)
    .title("Main")
    .height('100%')
    .width('100%')
    .backgroundColor('#F1F3F5')
  }
}

页面2:

js
@Entry
@Component
struct NextPage {
  pathStack: NavPathStack = new NavPathStack()  
  @State text: string = 'hello'  

  build() {
    NavDestination() {
      Text(this.text)
        .fontSize(50)
        .fontWeight(FontWeight.Bold)
    }
    .title('Detail')
    .onReady((context: NavDestinationContext) => {  
      this.pathStack = context.pathStack  
      const size = this.pathStack.size();  
      const params = this.pathStack.getParamByIndex(size - 1) as Record<string, string> | undefined 
      if (params) {   
		this.text = params.foo   
	  }  
    })  
  }
}

@Builder
export function NextPageBuilder() {
  NextPage()
}
@Entry
@Component
struct NextPage {
  pathStack: NavPathStack = new NavPathStack()  
  @State text: string = 'hello'  

  build() {
    NavDestination() {
      Text(this.text)
        .fontSize(50)
        .fontWeight(FontWeight.Bold)
    }
    .title('Detail')
    .onReady((context: NavDestinationContext) => {  
      this.pathStack = context.pathStack  
      const size = this.pathStack.size();  
      const params = this.pathStack.getParamByIndex(size - 1) as Record<string, string> | undefined 
      if (params) {   
		this.text = params.foo   
	  }  
    })  
  }
}

@Builder
export function NextPageBuilder() {
  NextPage()
}

和tabbar的配合

示例,用toolbarConfiguration模拟,不过下面写法不是最佳实践:

js
@Entry  
@Component  
struct Index {  
  pageInfos: NavPathStack = new NavPathStack()  
  TooTmp1: ToolbarItem = {  
    'value': "func",  
    'icon': "./image/ic_public_highlights.svg",  
    'action': () => {  
      this.tabBarIndex = 1  
    }  
  }  TooTmp2: ToolbarItem = {  
    'value': "func",  
    'action': () => {  
      this.tabBarIndex = 2  
    }  
  }  TooTmp3: ToolbarItem = {  
    'value': "func",  
    'action': () => {  
      this.tabBarIndex = 3  
    }  
  } 
   @State tabBarIndex: number = 1;  
  
  build() {  
    Navigation(this.pageInfos) {  
      if (this.tabBarIndex == 1) {  
        Text("hi1~")  
          .onClick(() => {  
            this.pageInfos.pushPath({ name: "NextPage" })  
          })  
      } else if (this.tabBarIndex == 2) {  
        Text("hi2~")  
          .onClick(() => {  
            this.pageInfos.pushPath({ name: "NextPage" })  
          })  
      } else if (this.tabBarIndex == 3) {  
        Text("hi3~")  
          .onClick(() => {  
            this.pageInfos.pushPath({ name: "NextPage" })  
          })  
      }  
    }    .mode(NavigationMode.Stack)  
    .title("Main")  
    .toolbarConfiguration([this.TooTmp1, this.TooTmp2, this.TooTmp3])  
    .height('100%')  
    .width('100%')  
    .backgroundColor('#F1F3F5')  
  }  
}
@Entry  
@Component  
struct Index {  
  pageInfos: NavPathStack = new NavPathStack()  
  TooTmp1: ToolbarItem = {  
    'value': "func",  
    'icon': "./image/ic_public_highlights.svg",  
    'action': () => {  
      this.tabBarIndex = 1  
    }  
  }  TooTmp2: ToolbarItem = {  
    'value': "func",  
    'action': () => {  
      this.tabBarIndex = 2  
    }  
  }  TooTmp3: ToolbarItem = {  
    'value': "func",  
    'action': () => {  
      this.tabBarIndex = 3  
    }  
  } 
   @State tabBarIndex: number = 1;  
  
  build() {  
    Navigation(this.pageInfos) {  
      if (this.tabBarIndex == 1) {  
        Text("hi1~")  
          .onClick(() => {  
            this.pageInfos.pushPath({ name: "NextPage" })  
          })  
      } else if (this.tabBarIndex == 2) {  
        Text("hi2~")  
          .onClick(() => {  
            this.pageInfos.pushPath({ name: "NextPage" })  
          })  
      } else if (this.tabBarIndex == 3) {  
        Text("hi3~")  
          .onClick(() => {  
            this.pageInfos.pushPath({ name: "NextPage" })  
          })  
      }  
    }    .mode(NavigationMode.Stack)  
    .title("Main")  
    .toolbarConfiguration([this.TooTmp1, this.TooTmp2, this.TooTmp3])  
    .height('100%')  
    .width('100%')  
    .backgroundColor('#F1F3F5')  
  }  
}

页面栈定制

见:页面栈继承示例代码

Q&A

跨包引用路由或资源

hideNavBar 和 hideTitleBar 的区别

hideTitleBar 这个比较简单,用于设置是否隐藏标题栏。

hideNavBar: 需要理解Navigation组件主要包含​导航页(NavBar)子页(NavDestination)。 设置 hideNavBar用于隐藏导航页。

hideNavBar设置是否隐藏导航栏。设置为true时,隐藏Navigation的导航栏,包括标题栏、内容区和工具栏。如果此时路由栈中存在NavDestination页面,则直接显示栈顶NavDestination页面,反之显示空白。

资源参考

应用导航设计-架构-最佳实践

页面路由-分包加载

方舟UI框架(ArkUI)-Q&A

Router切换Navigation-设置组件导航和页面路由