1e41f4b71Sopenharmony_ci# Component Navigation (Navigation) (Recommended) 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ciThe [Navigation](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md) component functions as the root container of a page and supports three display modes: single-page, column, and adaptive. It is applicable to routing within a module or across modules and useful in one-time development for multi-device deployment. Draw on this component's routing capability to create a smooth page transition experience, and explore its various title bar styles to present titles seamlessly linked with the content. On devices of different sizes, the **Navigation** component can automatically adapt to the display size and switch between display modes. 4e41f4b71Sopenharmony_ci 5e41f4b71Sopenharmony_ciThe **Navigation** component consists of the navigation page (**NavBar**) and subpage (**NavDestination**). The navigation page consists of the title bar (including the menu bar), content area, and toolbar. It can be hidden through the [hideNavBar](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#hidenavbar9) attribute. The navigation page does not exist in the page stack, and switching between this page and its subpages, as well as switching between subpages, can be implemented through routing. 6e41f4b71Sopenharmony_ci 7e41f4b71Sopenharmony_ciIn API version 9, you need to combine the **Navigation** component and the [\<NavRouter>](../reference/apis-arkui/arkui-ts/ts-basic-components-navrouter.md) component to implement page navigation. Since API version 10, you are advised to use the [NavPathStack](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#navpathstack10) component for the same purpose. 8e41f4b71Sopenharmony_ci 9e41f4b71Sopenharmony_ci 10e41f4b71Sopenharmony_ci## Setting the Page Display Mode 11e41f4b71Sopenharmony_ci 12e41f4b71Sopenharmony_ciThe **Navigation** component uses the **mode** attribute to set the page display mode. 13e41f4b71Sopenharmony_ci 14e41f4b71Sopenharmony_ci- Adaptive Mode 15e41f4b71Sopenharmony_ci 16e41f4b71Sopenharmony_ci By default, the **Navigation** component is in adaptive mode. In this case, the **mode** attribute is **NavigationMode.Auto**. In adaptive mode, when the device width is greater than or equal to the threshold (520 vp for API version 9 and earlier and 600 vp for API version 10 and later), the **Navigation** component uses the column mode. Otherwise, the **Navigation** component uses the single-page mode. 17e41f4b71Sopenharmony_ci 18e41f4b71Sopenharmony_ci 19e41f4b71Sopenharmony_ci ``` 20e41f4b71Sopenharmony_ci Navigation() { 21e41f4b71Sopenharmony_ci ... 22e41f4b71Sopenharmony_ci } 23e41f4b71Sopenharmony_ci .mode(NavigationMode.Auto) 24e41f4b71Sopenharmony_ci ``` 25e41f4b71Sopenharmony_ci 26e41f4b71Sopenharmony_ci- Single-page mode 27e41f4b71Sopenharmony_ci 28e41f4b71Sopenharmony_ci **Figure 1** Single-page mode 29e41f4b71Sopenharmony_ci 30e41f4b71Sopenharmony_ci  31e41f4b71Sopenharmony_ci 32e41f4b71Sopenharmony_ci Set **mode** to **NavigationMode.Stack** so that the **Navigation** component is displayed on a single page. 33e41f4b71Sopenharmony_ci 34e41f4b71Sopenharmony_ci 35e41f4b71Sopenharmony_ci ```ts 36e41f4b71Sopenharmony_ci Navigation() { 37e41f4b71Sopenharmony_ci ... 38e41f4b71Sopenharmony_ci } 39e41f4b71Sopenharmony_ci .mode(NavigationMode.Stack) 40e41f4b71Sopenharmony_ci ``` 41e41f4b71Sopenharmony_ci 42e41f4b71Sopenharmony_ci  43e41f4b71Sopenharmony_ci 44e41f4b71Sopenharmony_ci- Column mode 45e41f4b71Sopenharmony_ci 46e41f4b71Sopenharmony_ci **Figure 2** Column mode 47e41f4b71Sopenharmony_ci 48e41f4b71Sopenharmony_ci  49e41f4b71Sopenharmony_ci 50e41f4b71Sopenharmony_ci Set **mode** to **NavigationMode.Split** so that the **Navigation** component is displayed in columns. 51e41f4b71Sopenharmony_ci 52e41f4b71Sopenharmony_ci 53e41f4b71Sopenharmony_ci ```ts 54e41f4b71Sopenharmony_ci @Entry 55e41f4b71Sopenharmony_ci @Component 56e41f4b71Sopenharmony_ci struct NavigationExample { 57e41f4b71Sopenharmony_ci @State TooTmp: ToolbarItem = {'value': "func", 'icon': "./image/ic_public_highlights.svg", 'action': ()=> {}} 58e41f4b71Sopenharmony_ci @Provide('pageInfos') pageInfos: NavPathStack = new NavPathStack() 59e41f4b71Sopenharmony_ci private arr: number[] = [1, 2, 3]; 60e41f4b71Sopenharmony_ci 61e41f4b71Sopenharmony_ci @Builder 62e41f4b71Sopenharmony_ci PageMap(name: string) { 63e41f4b71Sopenharmony_ci if (name === "NavDestinationTitle1") { 64e41f4b71Sopenharmony_ci pageOneTmp() 65e41f4b71Sopenharmony_ci } else if (name === "NavDestinationTitle2") { 66e41f4b71Sopenharmony_ci pageTwoTmp() 67e41f4b71Sopenharmony_ci } else if (name === "NavDestinationTitle3") { 68e41f4b71Sopenharmony_ci pageThreeTmp() 69e41f4b71Sopenharmony_ci } 70e41f4b71Sopenharmony_ci } 71e41f4b71Sopenharmony_ci 72e41f4b71Sopenharmony_ci build() { 73e41f4b71Sopenharmony_ci Column() { 74e41f4b71Sopenharmony_ci Navigation(this.pageInfos) { 75e41f4b71Sopenharmony_ci TextInput({ placeholder: 'search...' }) 76e41f4b71Sopenharmony_ci .width("90%") 77e41f4b71Sopenharmony_ci .height(40) 78e41f4b71Sopenharmony_ci .backgroundColor('#FFFFFF') 79e41f4b71Sopenharmony_ci 80e41f4b71Sopenharmony_ci List({ space: 12 }) { 81e41f4b71Sopenharmony_ci ForEach(this.arr, (item:string) => { 82e41f4b71Sopenharmony_ci ListItem() { 83e41f4b71Sopenharmony_ci Text("NavRouter" + item) 84e41f4b71Sopenharmony_ci .width("100%") 85e41f4b71Sopenharmony_ci .height(72) 86e41f4b71Sopenharmony_ci .backgroundColor('#FFFFFF') 87e41f4b71Sopenharmony_ci .borderRadius(24) 88e41f4b71Sopenharmony_ci .fontSize(16) 89e41f4b71Sopenharmony_ci .fontWeight(500) 90e41f4b71Sopenharmony_ci .textAlign(TextAlign.Center) 91e41f4b71Sopenharmony_ci .onClick(()=>{ 92e41f4b71Sopenharmony_ci this.pageInfos.pushPath({ name: "NavDestinationTitle" + item}) 93e41f4b71Sopenharmony_ci }) 94e41f4b71Sopenharmony_ci } 95e41f4b71Sopenharmony_ci }, (item:string):string => item) 96e41f4b71Sopenharmony_ci } 97e41f4b71Sopenharmony_ci .width("90%") 98e41f4b71Sopenharmony_ci .margin({ top: 12 }) 99e41f4b71Sopenharmony_ci } 100e41f4b71Sopenharmony_ci .title ("Main Title") 101e41f4b71Sopenharmony_ci .mode(NavigationMode.Split) 102e41f4b71Sopenharmony_ci .navDestination(this.PageMap) 103e41f4b71Sopenharmony_ci .menus([ 104e41f4b71Sopenharmony_ci {value: "", icon: "./image/ic_public_search.svg", action: ()=> {}}, 105e41f4b71Sopenharmony_ci {value: "", icon: "./image/ic_public_add.svg", action: ()=> {}}, 106e41f4b71Sopenharmony_ci {value: "", icon: "./image/ic_public_add.svg", action: ()=> {}}, 107e41f4b71Sopenharmony_ci {value: "", icon: "./image/ic_public_add.svg", action: ()=> {}}, 108e41f4b71Sopenharmony_ci {value: "", icon: "./image/ic_public_add.svg", action: ()=> {}} 109e41f4b71Sopenharmony_ci ]) 110e41f4b71Sopenharmony_ci .toolbarConfiguration([this.TooTmp, this.TooTmp, this.TooTmp]) 111e41f4b71Sopenharmony_ci } 112e41f4b71Sopenharmony_ci .height('100%') 113e41f4b71Sopenharmony_ci .width('100%') 114e41f4b71Sopenharmony_ci .backgroundColor('#F1F3F5') 115e41f4b71Sopenharmony_ci } 116e41f4b71Sopenharmony_ci } 117e41f4b71Sopenharmony_ci 118e41f4b71Sopenharmony_ci // PageOne.ets 119e41f4b71Sopenharmony_ci @Component 120e41f4b71Sopenharmony_ci export struct pageOneTmp { 121e41f4b71Sopenharmony_ci @Consume('pageInfos') pageInfos: NavPathStack; 122e41f4b71Sopenharmony_ci build() { 123e41f4b71Sopenharmony_ci NavDestination() { 124e41f4b71Sopenharmony_ci Column() { 125e41f4b71Sopenharmony_ci Text("NavDestinationContent1") 126e41f4b71Sopenharmony_ci }.width('100%').height('100%') 127e41f4b71Sopenharmony_ci }.title("NavDestinationTitle1") 128e41f4b71Sopenharmony_ci .onBackPressed(() => { 129e41f4b71Sopenharmony_ci const popDestinationInfo = this.pageInfos.pop() // Pop the top element out of the navigation stack. 130e41f4b71Sopenharmony_ci console.log('pop' + 'Return value' + JSON.stringify(popDestinationInfo)) 131e41f4b71Sopenharmony_ci return true 132e41f4b71Sopenharmony_ci }) 133e41f4b71Sopenharmony_ci } 134e41f4b71Sopenharmony_ci } 135e41f4b71Sopenharmony_ci 136e41f4b71Sopenharmony_ci // PageTwo.ets 137e41f4b71Sopenharmony_ci @Component 138e41f4b71Sopenharmony_ci export struct pageTwoTmp { 139e41f4b71Sopenharmony_ci @Consume('pageInfos') pageInfos: NavPathStack; 140e41f4b71Sopenharmony_ci build() { 141e41f4b71Sopenharmony_ci NavDestination() { 142e41f4b71Sopenharmony_ci Column() { 143e41f4b71Sopenharmony_ci Text("NavDestinationContent2") 144e41f4b71Sopenharmony_ci }.width('100%').height('100%') 145e41f4b71Sopenharmony_ci }.title("NavDestinationTitle2") 146e41f4b71Sopenharmony_ci .onBackPressed(() => { 147e41f4b71Sopenharmony_ci const popDestinationInfo = this.pageInfos.pop() // Pop the top element out of the navigation stack. 148e41f4b71Sopenharmony_ci console.log('pop' + 'Return value' + JSON.stringify(popDestinationInfo)) 149e41f4b71Sopenharmony_ci return true 150e41f4b71Sopenharmony_ci }) 151e41f4b71Sopenharmony_ci } 152e41f4b71Sopenharmony_ci } 153e41f4b71Sopenharmony_ci 154e41f4b71Sopenharmony_ci // PageThree.ets 155e41f4b71Sopenharmony_ci @Component 156e41f4b71Sopenharmony_ci export struct pageThreeTmp { 157e41f4b71Sopenharmony_ci @Consume('pageInfos') pageInfos: NavPathStack; 158e41f4b71Sopenharmony_ci build() { 159e41f4b71Sopenharmony_ci NavDestination() { 160e41f4b71Sopenharmony_ci Column() { 161e41f4b71Sopenharmony_ci Text("NavDestinationContent3") 162e41f4b71Sopenharmony_ci }.width('100%').height('100%') 163e41f4b71Sopenharmony_ci }.title("NavDestinationTitle3") 164e41f4b71Sopenharmony_ci .onBackPressed(() => { 165e41f4b71Sopenharmony_ci const popDestinationInfo = this.pageInfos.pop() // Pop the top element out of the navigation stack. 166e41f4b71Sopenharmony_ci console.log('pop' + 'Return value' + JSON.stringify(popDestinationInfo)) 167e41f4b71Sopenharmony_ci return true 168e41f4b71Sopenharmony_ci }) 169e41f4b71Sopenharmony_ci } 170e41f4b71Sopenharmony_ci } 171e41f4b71Sopenharmony_ci ``` 172e41f4b71Sopenharmony_ci 173e41f4b71Sopenharmony_ci  174e41f4b71Sopenharmony_ci 175e41f4b71Sopenharmony_ci 176e41f4b71Sopenharmony_ci## Setting the Title Bar Mode 177e41f4b71Sopenharmony_ci 178e41f4b71Sopenharmony_ciThe title bar is on the top of the page and is used to display the page name and operation entry. The **Navigation** component uses the **titleMode** attribute to set the title bar mode. 179e41f4b71Sopenharmony_ci 180e41f4b71Sopenharmony_ci- Mini mode 181e41f4b71Sopenharmony_ci 182e41f4b71Sopenharmony_ci Applicable when the title of a level-1 page does not need to be highlighted. 183e41f4b71Sopenharmony_ci 184e41f4b71Sopenharmony_ci **Figure 3** Title bar in Mini mode 185e41f4b71Sopenharmony_ci 186e41f4b71Sopenharmony_ci  187e41f4b71Sopenharmony_ci 188e41f4b71Sopenharmony_ci 189e41f4b71Sopenharmony_ci ```ts 190e41f4b71Sopenharmony_ci Navigation() { 191e41f4b71Sopenharmony_ci ... 192e41f4b71Sopenharmony_ci } 193e41f4b71Sopenharmony_ci .titleMode(NavigationTitleMode.Mini) 194e41f4b71Sopenharmony_ci ``` 195e41f4b71Sopenharmony_ci 196e41f4b71Sopenharmony_ci 197e41f4b71Sopenharmony_ci- Full mode 198e41f4b71Sopenharmony_ci 199e41f4b71Sopenharmony_ci Applicable when the title of a level-1 page needs to be highlighted. 200e41f4b71Sopenharmony_ci 201e41f4b71Sopenharmony_ci **Figure 4** Title bar in Full mode 202e41f4b71Sopenharmony_ci 203e41f4b71Sopenharmony_ci  204e41f4b71Sopenharmony_ci 205e41f4b71Sopenharmony_ci 206e41f4b71Sopenharmony_ci ```ts 207e41f4b71Sopenharmony_ci Navigation() { 208e41f4b71Sopenharmony_ci ... 209e41f4b71Sopenharmony_ci } 210e41f4b71Sopenharmony_ci .titleMode(NavigationTitleMode.Full) 211e41f4b71Sopenharmony_ci ``` 212e41f4b71Sopenharmony_ci 213e41f4b71Sopenharmony_ci 214e41f4b71Sopenharmony_ci## Setting the Menu Bar 215e41f4b71Sopenharmony_ci 216e41f4b71Sopenharmony_ciThe menu bar is in the upper right corner of the **Navigation** component. You can set the menu bar through the **menus** attribute, which supports two parameter types: Array<[NavigationMenuItem](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#navigationmenuitem)> and CustomBuilder. When the Array\<NavigationMenuItem> type is used, a maximum of three icons can be displayed in portrait mode and a maximum of five icons can be displayed in landscape mode. Extra icons will be placed in the automatically generated More icons. 217e41f4b71Sopenharmony_ci 218e41f4b71Sopenharmony_ci**Figure 5** Menu bar with three icons 219e41f4b71Sopenharmony_ci 220e41f4b71Sopenharmony_ci 221e41f4b71Sopenharmony_ci 222e41f4b71Sopenharmony_ci```ts 223e41f4b71Sopenharmony_cilet TooTmp: NavigationMenuItem = {'value': "", 'icon': "./image/ic_public_highlights.svg", 'action': ()=> {}} 224e41f4b71Sopenharmony_ciNavigation() { 225e41f4b71Sopenharmony_ci ... 226e41f4b71Sopenharmony_ci} 227e41f4b71Sopenharmony_ci.menus([TooTmp, 228e41f4b71Sopenharmony_ci TooTmp, 229e41f4b71Sopenharmony_ci TooTmp]) 230e41f4b71Sopenharmony_ci``` 231e41f4b71Sopenharmony_ci 232e41f4b71Sopenharmony_ciYou can also reference images in the **resources** folder. 233e41f4b71Sopenharmony_ci 234e41f4b71Sopenharmony_ci```ts 235e41f4b71Sopenharmony_cilet TooTmp: NavigationMenuItem = {'value': "", 'icon': "resources/base/media/ic_public_highlights.svg", 'action': ()=> {}} 236e41f4b71Sopenharmony_ciNavigation() { 237e41f4b71Sopenharmony_ci ... 238e41f4b71Sopenharmony_ci} 239e41f4b71Sopenharmony_ci.menus([TooTmp, 240e41f4b71Sopenharmony_ci TooTmp, 241e41f4b71Sopenharmony_ci TooTmp]) 242e41f4b71Sopenharmony_ci``` 243e41f4b71Sopenharmony_ci 244e41f4b71Sopenharmony_ci**Figure 6** Menu bar with four icons 245e41f4b71Sopenharmony_ci 246e41f4b71Sopenharmony_ci 247e41f4b71Sopenharmony_ci 248e41f4b71Sopenharmony_ci```ts 249e41f4b71Sopenharmony_cilet TooTmp: NavigationMenuItem = {'value': "", 'icon': "./image/ic_public_highlights.svg", 'action': ()=> {}} 250e41f4b71Sopenharmony_ciNavigation() { 251e41f4b71Sopenharmony_ci ... 252e41f4b71Sopenharmony_ci} 253e41f4b71Sopenharmony_ci.menus([TooTmp, 254e41f4b71Sopenharmony_ci TooTmp, 255e41f4b71Sopenharmony_ci TooTmp, 256e41f4b71Sopenharmony_ci TooTmp]) 257e41f4b71Sopenharmony_ci``` 258e41f4b71Sopenharmony_ci 259e41f4b71Sopenharmony_ci 260e41f4b71Sopenharmony_ci## Setting the Toolbar 261e41f4b71Sopenharmony_ci 262e41f4b71Sopenharmony_ciThe toolbar is located at the bottom of the **Navigation** component. You can set the toolbar through the **toolbarConfiguration** attribute. 263e41f4b71Sopenharmony_ci 264e41f4b71Sopenharmony_ci 265e41f4b71Sopenharmony_ci **Figure 7** Toolbar 266e41f4b71Sopenharmony_ci 267e41f4b71Sopenharmony_ci 268e41f4b71Sopenharmony_ci 269e41f4b71Sopenharmony_ci```ts 270e41f4b71Sopenharmony_cilet TooTmp: ToolbarItem = {'value': "func", 'icon': "./image/ic_public_highlights.svg", 'action': ()=> {}} 271e41f4b71Sopenharmony_cilet TooBar: ToolbarItem[] = [TooTmp,TooTmp,TooTmp] 272e41f4b71Sopenharmony_ciNavigation() { 273e41f4b71Sopenharmony_ci ... 274e41f4b71Sopenharmony_ci} 275e41f4b71Sopenharmony_ci.toolbarConfiguration(TooBar) 276e41f4b71Sopenharmony_ci``` 277e41f4b71Sopenharmony_ci 278e41f4b71Sopenharmony_ci## Route Operations 279e41f4b71Sopenharmony_ci 280e41f4b71Sopenharmony_ciNavigation-related routing operations are all based on the APIs provided by [NavPathStack](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#navpathstack10). For each **Navigation** component, a **NavPathStack** object must be created and passed in to manage pages. The router operations mainly involve page navigation, page return, page replacement, page deletion, parameter acquisition, and routing interception. 281e41f4b71Sopenharmony_ci 282e41f4b71Sopenharmony_ci**NavPathStack** can be inherited since API version 12. You can customize attributes and methods in derived classes or override methods of the parent class. Derived class objects can be used in place of the base class **NavPathStack** objects. For details about the sample code, see [Example 10](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#example-10). 283e41f4b71Sopenharmony_ci 284e41f4b71Sopenharmony_ci```ts 285e41f4b71Sopenharmony_ci@Entry 286e41f4b71Sopenharmony_ci@Component 287e41f4b71Sopenharmony_cistruct Index { 288e41f4b71Sopenharmony_ci // Create a NavPathStack object and pass it to Navigation. 289e41f4b71Sopenharmony_ci pageStack: NavPathStack = new NavPathStack() 290e41f4b71Sopenharmony_ci 291e41f4b71Sopenharmony_ci build() { 292e41f4b71Sopenharmony_ci Navigation(this.pageStack) { 293e41f4b71Sopenharmony_ci } 294e41f4b71Sopenharmony_ci .title('Main') 295e41f4b71Sopenharmony_ci } 296e41f4b71Sopenharmony_ci} 297e41f4b71Sopenharmony_ci``` 298e41f4b71Sopenharmony_ci 299e41f4b71Sopenharmony_ci### Page Navigation 300e41f4b71Sopenharmony_ci 301e41f4b71Sopenharmony_ci**NavPathStack** implements the following types of page navigation through **Push** related APIs: 302e41f4b71Sopenharmony_ci 303e41f4b71Sopenharmony_ci1. Normal navigation: Navigation is conducted by page name and allows for passing of **param**. 304e41f4b71Sopenharmony_ci 305e41f4b71Sopenharmony_ci ```ts 306e41f4b71Sopenharmony_ci this.pageStack.pushPath({ name: "PageOne", param: "PageOne Param" }) 307e41f4b71Sopenharmony_ci this.pageStack.pushPathByName("PageOne", "PageOne Param") 308e41f4b71Sopenharmony_ci ``` 309e41f4b71Sopenharmony_ci 310e41f4b71Sopenharmony_ci2. Navigation with a return callback: An **onPop** callback is added during navigation to obtain return information and process it upon page popping. 311e41f4b71Sopenharmony_ci 312e41f4b71Sopenharmony_ci ```ts 313e41f4b71Sopenharmony_ci this.pageStack.pushPathByName('PageOne', "PageOne Param", (popInfo) => { 314e41f4b71Sopenharmony_ci console.log('Pop page name is: ' + popInfo.info.name + ', result: ' + JSON.stringify(popInfo.result)) 315e41f4b71Sopenharmony_ci }); 316e41f4b71Sopenharmony_ci ``` 317e41f4b71Sopenharmony_ci 318e41f4b71Sopenharmony_ci3. Navigation with an error code: An asynchronous callback is triggered at the end of navigation, returning error code information. 319e41f4b71Sopenharmony_ci 320e41f4b71Sopenharmony_ci ```ts 321e41f4b71Sopenharmony_ci this.pageStack.pushDestinationByName('PageOne', "PageOne Param") 322e41f4b71Sopenharmony_ci .catch((error: BusinessError) => { 323e41f4b71Sopenharmony_ci console.error(`Push destination failed, error code = ${error.code}, error.message = ${error.message}.`); 324e41f4b71Sopenharmony_ci }).then(() => { 325e41f4b71Sopenharmony_ci console.error('Push destination succeed.'); 326e41f4b71Sopenharmony_ci }); 327e41f4b71Sopenharmony_ci ``` 328e41f4b71Sopenharmony_ci 329e41f4b71Sopenharmony_ci### Page Return 330e41f4b71Sopenharmony_ci 331e41f4b71Sopenharmony_ci**NavPathStack** implements the page return feature through **Pop** related APIs. 332e41f4b71Sopenharmony_ci 333e41f4b71Sopenharmony_ci```ts 334e41f4b71Sopenharmony_ci// Return to the previous page. 335e41f4b71Sopenharmony_cithis.pageStack.pop() 336e41f4b71Sopenharmony_ci// Return to the previous PageOne page. 337e41f4b71Sopenharmony_cithis.pageStack.popToName("PageOne") 338e41f4b71Sopenharmony_ci// Return to the page whose index is 1. 339e41f4b71Sopenharmony_cithis.pageStack.popToIndex(1) 340e41f4b71Sopenharmony_ci// Return to the root home page (clear all pages in the stack). 341e41f4b71Sopenharmony_cithis.pageStack.clear() 342e41f4b71Sopenharmony_ci``` 343e41f4b71Sopenharmony_ci 344e41f4b71Sopenharmony_ci### Page Replacement 345e41f4b71Sopenharmony_ci 346e41f4b71Sopenharmony_ciNavPathStack implements the page replacement feature through **Replace** related APIs. 347e41f4b71Sopenharmony_ci 348e41f4b71Sopenharmony_ci```ts 349e41f4b71Sopenharmony_ci// Replace the top page of the stack with PageOne. 350e41f4b71Sopenharmony_cithis.pageStack.replacePath({ name: "PageOne", param: "PageOne Param" }) 351e41f4b71Sopenharmony_cithis.pageStack.replacePathByName("PageOne", "PageOne Param") 352e41f4b71Sopenharmony_ci``` 353e41f4b71Sopenharmony_ci 354e41f4b71Sopenharmony_ci### Page Deletion 355e41f4b71Sopenharmony_ci 356e41f4b71Sopenharmony_ci**NavPathStack** implements the page deletion feature through **Remove** related APIs. 357e41f4b71Sopenharmony_ci 358e41f4b71Sopenharmony_ci```ts 359e41f4b71Sopenharmony_ci// Remove all pages whose name is PageOne from the stack. 360e41f4b71Sopenharmony_cithis.pageStack.removeByName("PageOne") 361e41f4b71Sopenharmony_ci// Remove the page with the specified index. 362e41f4b71Sopenharmony_cithis.pageStack.removeByIndexes([1,3,5]) 363e41f4b71Sopenharmony_ci``` 364e41f4b71Sopenharmony_ci 365e41f4b71Sopenharmony_ci### Parameter Acquisition 366e41f4b71Sopenharmony_ci 367e41f4b71Sopenharmony_ci**NavPathStack** obtains parameters of the page through **Get** related APIs. 368e41f4b71Sopenharmony_ci 369e41f4b71Sopenharmony_ci```ts 370e41f4b71Sopenharmony_ci// Obtain all page names in the stack. 371e41f4b71Sopenharmony_cithis.pageStack.getAllPathName() 372e41f4b71Sopenharmony_ci// Obtain the parameters of the page whose index is 1. 373e41f4b71Sopenharmony_cithis.pageStack.getParamByIndex(1) 374e41f4b71Sopenharmony_ci// Obtain the parameters of the PageOne page. 375e41f4b71Sopenharmony_cithis.pageStack.getParamByName("PageOne") 376e41f4b71Sopenharmony_ci// Obtain the index set of the PageOne page. 377e41f4b71Sopenharmony_cithis.pageStack.getIndexByName("PageOne") 378e41f4b71Sopenharmony_ci``` 379e41f4b71Sopenharmony_ci 380e41f4b71Sopenharmony_ci### Route Interception 381e41f4b71Sopenharmony_ci 382e41f4b71Sopenharmony_ci**NavPathStack** provides the [setInterception](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#setinterception12) API to set callbacks for page navigation interception of **Navigation**. This API requires passing in a **NavigationInterception** object, which contains three callback functions described below. 383e41f4b71Sopenharmony_ci 384e41f4b71Sopenharmony_ci| Name | Description | 385e41f4b71Sopenharmony_ci| ------------ | ------------------------------------------------------ | 386e41f4b71Sopenharmony_ci| willShow | Callback invoked when the page is about to be navigated, allowing for stack operations, which are effective in the current navigation. | 387e41f4b71Sopenharmony_ci| didShow | Callback invoked after the page is navigated. Stack operations in this callback are effective in the next navigation. | 388e41f4b71Sopenharmony_ci| modeChange | Callback invoked when the display mode of the **Navigation** component switches between single-column and dual-column. | 389e41f4b71Sopenharmony_ci 390e41f4b71Sopenharmony_ci> **NOTE** 391e41f4b71Sopenharmony_ci> 392e41f4b71Sopenharmony_ci> The navigation stack has already changed when any of the preceding callbacks is invoked. 393e41f4b71Sopenharmony_ci 394e41f4b71Sopenharmony_ciYou can implement the capability to intercept and redirect in the **willShow** callback by modifying the route stack. 395e41f4b71Sopenharmony_ci 396e41f4b71Sopenharmony_ci```ts 397e41f4b71Sopenharmony_cithis.pageStack.setInterception({ 398e41f4b71Sopenharmony_ci willShow: (from: NavDestinationContext | "navBar", to: NavDestinationContext | "navBar", 399e41f4b71Sopenharmony_ci operation: NavigationOperation, animated: boolean) => { 400e41f4b71Sopenharmony_ci if (typeof to === "string") { 401e41f4b71Sopenharmony_ci console.log("target page is navigation home page."); 402e41f4b71Sopenharmony_ci return; 403e41f4b71Sopenharmony_ci } 404e41f4b71Sopenharmony_ci // Redirect navigation to PageTwo to PageOne. 405e41f4b71Sopenharmony_ci let target: NavDestinationContext = to as NavDestinationContext; 406e41f4b71Sopenharmony_ci if (target.pathInfo.name === 'PageTwo') { 407e41f4b71Sopenharmony_ci target.pathStack.pop(); 408e41f4b71Sopenharmony_ci target.pathStack.pushPathByName('PageOne', null); 409e41f4b71Sopenharmony_ci } 410e41f4b71Sopenharmony_ci } 411e41f4b71Sopenharmony_ci}) 412e41f4b71Sopenharmony_ci``` 413e41f4b71Sopenharmony_ci 414e41f4b71Sopenharmony_ci## Subpage 415e41f4b71Sopenharmony_ci 416e41f4b71Sopenharmony_ci[NavDestination](../reference/apis-arkui/arkui-ts/ts-basic-components-navdestination.md) is the root container for **Navigation** subpages, used to hold some special attributes as well as lifecycles of subpages. You can set separate attributes such as the title bar and menu bar for **NavDestination**, in the same way you set attributes for **Navigation**. You can also set different display modes for **NavDestination** through the **mode** attribute to meet different page requirements. 417e41f4b71Sopenharmony_ci 418e41f4b71Sopenharmony_ci### Page Display Mode 419e41f4b71Sopenharmony_ci 420e41f4b71Sopenharmony_ci- Standard mode 421e41f4b71Sopenharmony_ci 422e41f4b71Sopenharmony_ci By default, subpages in the **\<NavDestination>** component are in standard mode, which corresponds to the **NavDestinationMode.STANDARD** value of the **mode** attribute. The lifecycle of a standard type **NavDestination** follows the changes in its position in the **NavPathStack**. 423e41f4b71Sopenharmony_ci 424e41f4b71Sopenharmony_ci- Dialog mode 425e41f4b71Sopenharmony_ci 426e41f4b71Sopenharmony_ci With **mode** set to **NavDestinationMode.DIALOG**, a **NavDestination** The appearance and disappearance of the dialog-type **NavDestination** will not affect the display and lifecycle of the underlying standard-type **NavDestination**, and the two can be displayed at the same time. 427e41f4b71Sopenharmony_ci 428e41f4b71Sopenharmony_ci ```ts 429e41f4b71Sopenharmony_ci // Dialog NavDestination 430e41f4b71Sopenharmony_ci @Entry 431e41f4b71Sopenharmony_ci @Component 432e41f4b71Sopenharmony_ci struct Index { 433e41f4b71Sopenharmony_ci @Provide('NavPathStack') pageStack: NavPathStack = new NavPathStack() 434e41f4b71Sopenharmony_ci 435e41f4b71Sopenharmony_ci @Builder 436e41f4b71Sopenharmony_ci PagesMap(name: string) { 437e41f4b71Sopenharmony_ci if (name == 'DialogPage') { 438e41f4b71Sopenharmony_ci DialogPage() 439e41f4b71Sopenharmony_ci } 440e41f4b71Sopenharmony_ci } 441e41f4b71Sopenharmony_ci 442e41f4b71Sopenharmony_ci build() { 443e41f4b71Sopenharmony_ci Navigation(this.pageStack) { 444e41f4b71Sopenharmony_ci Button('Push DialogPage') 445e41f4b71Sopenharmony_ci .margin(20) 446e41f4b71Sopenharmony_ci .width('80%') 447e41f4b71Sopenharmony_ci .onClick(() => { 448e41f4b71Sopenharmony_ci this.pageStack.pushPathByName('DialogPage', ''); 449e41f4b71Sopenharmony_ci }) 450e41f4b71Sopenharmony_ci } 451e41f4b71Sopenharmony_ci .mode(NavigationMode.Stack) 452e41f4b71Sopenharmony_ci .title('Main') 453e41f4b71Sopenharmony_ci .navDestination(this.PagesMap) 454e41f4b71Sopenharmony_ci } 455e41f4b71Sopenharmony_ci } 456e41f4b71Sopenharmony_ci 457e41f4b71Sopenharmony_ci @Component 458e41f4b71Sopenharmony_ci export struct DialogPage { 459e41f4b71Sopenharmony_ci @Consume('NavPathStack') pageStack: NavPathStack; 460e41f4b71Sopenharmony_ci 461e41f4b71Sopenharmony_ci build() { 462e41f4b71Sopenharmony_ci NavDestination() { 463e41f4b71Sopenharmony_ci Stack({ alignContent: Alignment.Center }) { 464e41f4b71Sopenharmony_ci Column() { 465e41f4b71Sopenharmony_ci Text("Dialog NavDestination") 466e41f4b71Sopenharmony_ci .fontSize(20) 467e41f4b71Sopenharmony_ci .margin({ bottom: 100 }) 468e41f4b71Sopenharmony_ci Button("Close").onClick(() => { 469e41f4b71Sopenharmony_ci this.pageStack.pop() 470e41f4b71Sopenharmony_ci }).width('30%') 471e41f4b71Sopenharmony_ci } 472e41f4b71Sopenharmony_ci .justifyContent(FlexAlign.Center) 473e41f4b71Sopenharmony_ci .backgroundColor(Color.White) 474e41f4b71Sopenharmony_ci .borderRadius(10) 475e41f4b71Sopenharmony_ci .height('30%') 476e41f4b71Sopenharmony_ci .width('80%') 477e41f4b71Sopenharmony_ci }.height("100%").width('100%') 478e41f4b71Sopenharmony_ci } 479e41f4b71Sopenharmony_ci .backgroundColor('rgba(0,0,0,0.5)') 480e41f4b71Sopenharmony_ci .hideTitleBar(true) 481e41f4b71Sopenharmony_ci .mode(NavDestinationMode.DIALOG) 482e41f4b71Sopenharmony_ci } 483e41f4b71Sopenharmony_ci } 484e41f4b71Sopenharmony_ci ``` 485e41f4b71Sopenharmony_ci  486e41f4b71Sopenharmony_ci 487e41f4b71Sopenharmony_ci### Page Lifecycle 488e41f4b71Sopenharmony_ci 489e41f4b71Sopenharmony_ciAs a routing container, **Navigation**'s lifecycle is carried on the **NavDestination** component, which is opened in the form of component events. 490e41f4b71Sopenharmony_ci 491e41f4b71Sopenharmony_ciIts lifecycle can be roughly divided into three categories: custom component lifecycle, universal component lifecycle, and its own lifecycle (where **aboutToAppear** and **aboutToDisappear** are [custom component lifecycle callbacks](../reference/apis-arkui/arkui-ts/ts-custom-component-lifecycle.md) and exist when **NavDestination** contains custom components; **OnAppear** and **OnDisappear** are [universal component lifecycle](../reference/apis-arkui/arkui-ts/ts-universal-events-show-hide.md); the remaining are unique to **NavDestination**) 492e41f4b71Sopenharmony_ci 493e41f4b71Sopenharmony_ciThe following figure shows the lifecycle. 494e41f4b71Sopenharmony_ci 495e41f4b71Sopenharmony_ci 496e41f4b71Sopenharmony_ci 497e41f4b71Sopenharmony_ci- **aboutToAppear**: Invoked when the custom component is about to appear. Specifically, it is invoked after a new instance of the custom component is created and before its **build()** function is executed (before the creation of **NavDestination**). You can change state variables in this callback, and the changes take effect in the subsequent execution of **build()**. 498e41f4b71Sopenharmony_ci- **onWillAppear**: invoked after the **NavDestination** component is created and before it is mounted to the component tree. Changing the state variable in this callback takes effect in the current frame. 499e41f4b71Sopenharmony_ci- **onAppear**: invoked when the **NavDestination** component is mounted to the component tree. It is a universal lifecycle event. 500e41f4b71Sopenharmony_ci- **onWillShow**: invoked before the **NavDestination** component layout is displayed. In this case, the page is invisible. (This callback is not invoked when the application is switched to the foreground.) 501e41f4b71Sopenharmony_ci- **onShown**: invoked after the **NavDestination** component layout is displayed. At this time, the page layout is complete. 502e41f4b71Sopenharmony_ci- **onWillHide**: invoked when the **NavDestination** component is about to be hidden (it is not invoked when the application is switched to the background). 503e41f4b71Sopenharmony_ci- **onHidden**: invoked after the **NavDestination** component is hidden (when a non-top page is pushed into the stack, the top page pops out of the stack, or the application is switched to the background). 504e41f4b71Sopenharmony_ci- **onWillDisappear**: invoked before the **NavDestination** component is about to be destroyed. If there is a transition animation, this callback is invoked before the animation (when the top page of the stack pops out of the stack). 505e41f4b71Sopenharmony_ci- **onDisappear**: invoked when the **NavDestination** component is unloaded and destroyed from the component tree. It is a universal lifecycle event. 506e41f4b71Sopenharmony_ci- **aboutToDisappear**: invoked before the custom component is destroyed. The state variable cannot be changed in this callback. 507e41f4b71Sopenharmony_ci 508e41f4b71Sopenharmony_ci### Page Listening and Query 509e41f4b71Sopenharmony_ci 510e41f4b71Sopenharmony_ciTo facilitate the decoupling of components from pages, custom components within **NavDestination** subpages can listen for or query some page status information through global APIs. 511e41f4b71Sopenharmony_ci 512e41f4b71Sopenharmony_ci- Page information query 513e41f4b71Sopenharmony_ci 514e41f4b71Sopenharmony_ci Custom components provide the [queryNavDestinationInfo](../reference/apis-arkui/arkui-ts/ts-custom-component-api.md#querynavdestinationinfo) API, which can be used to query the information of the current page within **NavDestination**. The return value is [NavDestinationInfo](../reference/apis-arkui/js-apis-arkui-observer.md#navdestinationinfo). If the query fails, the return value is **undefined**. 515e41f4b71Sopenharmony_ci 516e41f4b71Sopenharmony_ci ```ts 517e41f4b71Sopenharmony_ci import { uiObserver } from '@kit.ArkUI'; 518e41f4b71Sopenharmony_ci 519e41f4b71Sopenharmony_ci // Custom components within NavDestination 520e41f4b71Sopenharmony_ci @Component 521e41f4b71Sopenharmony_ci struct MyComponent { 522e41f4b71Sopenharmony_ci navDesInfo: uiObserver.NavDestinationInfo | undefined 523e41f4b71Sopenharmony_ci 524e41f4b71Sopenharmony_ci aboutToAppear(): void { 525e41f4b71Sopenharmony_ci this.navDesInfo = this.queryNavDestinationInfo(); 526e41f4b71Sopenharmony_ci } 527e41f4b71Sopenharmony_ci 528e41f4b71Sopenharmony_ci build() { 529e41f4b71Sopenharmony_ci Column() { 530e41f4b71Sopenharmony_ci Text("Page name: " + this.navDesInfo?.name) 531e41f4b71Sopenharmony_ci }.width('100%').height('100%') 532e41f4b71Sopenharmony_ci } 533e41f4b71Sopenharmony_ci } 534e41f4b71Sopenharmony_ci ``` 535e41f4b71Sopenharmony_ci- Page status listening 536e41f4b71Sopenharmony_ci 537e41f4b71Sopenharmony_ci The registration API provided by [@ohos.arkui.observer](../reference/apis-arkui/js-apis-arkui-observer.md#observeronnavdestinationupdate) can be used to listen for the lifecycle changes of **NavDestination**. The usage is as follows: 538e41f4b71Sopenharmony_ci 539e41f4b71Sopenharmony_ci ```ts 540e41f4b71Sopenharmony_ci uiObserver.on('navDestinationUpdate', (info) => { 541e41f4b71Sopenharmony_ci console.info('NavDestination state update', JSON.stringify(info)); 542e41f4b71Sopenharmony_ci }); 543e41f4b71Sopenharmony_ci ``` 544e41f4b71Sopenharmony_ci 545e41f4b71Sopenharmony_ci You can also register a callback for page switching status to obtain the corresponding page information [NavDestinationSwitchInfo](../reference/apis-arkui/js-apis-arkui-observer.md#navdestinationswitchinfo12) when a page route switching occurs, and it provides different listening scopes for UIAbilityContext and UIContext: 546e41f4b71Sopenharmony_ci 547e41f4b71Sopenharmony_ci ```ts 548e41f4b71Sopenharmony_ci // Used in UIAbility 549e41f4b71Sopenharmony_ci import { UIContext, uiObserver } from '@kit.ArkUI'; 550e41f4b71Sopenharmony_ci 551e41f4b71Sopenharmony_ci // callBackFunc is a callback defined by you. 552e41f4b71Sopenharmony_ci function callBackFunc(info: uiObserver.NavDestinationSwitchInfo) {} 553e41f4b71Sopenharmony_ci uiObserver.on('navDestinationSwitch', this.context, callBackFunc); 554e41f4b71Sopenharmony_ci 555e41f4b71Sopenharmony_ci // The getUIContext() API of the window can be used to obtain the corresponding UIContent. 556e41f4b71Sopenharmony_ci uiContext: UIContext | null = null; 557e41f4b71Sopenharmony_ci uiObserver.on('navDestinationSwitch', this.uiContext, callBackFunc); 558e41f4b71Sopenharmony_ci ``` 559e41f4b71Sopenharmony_ci 560e41f4b71Sopenharmony_ci## Page Transition 561e41f4b71Sopenharmony_ci 562e41f4b71Sopenharmony_ci**Navigation** provides default transition animations for page switching: Different transition effects are initiated for different operations on the page stack (dialog-type pages have no transition animation by default). **Navigation** also provides the capability to disable system transitions, customize transitions, and define shared element transitions. 563e41f4b71Sopenharmony_ci 564e41f4b71Sopenharmony_ci### Disabling Transitions 565e41f4b71Sopenharmony_ci 566e41f4b71Sopenharmony_ci- On a Global Basis 567e41f4b71Sopenharmony_ci 568e41f4b71Sopenharmony_ci To enable or disable all transition animations in the current **Navigation** component, you can use the [disableAnimation](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#disableanimation11) API provided in **NavPathStack**. 569e41f4b71Sopenharmony_ci ```ts 570e41f4b71Sopenharmony_ci pageStack: NavPathStack = new NavPathStack() 571e41f4b71Sopenharmony_ci 572e41f4b71Sopenharmony_ci aboutToAppear(): void { 573e41f4b71Sopenharmony_ci this.pageStack.disableAnimation(true) 574e41f4b71Sopenharmony_ci } 575e41f4b71Sopenharmony_ci ``` 576e41f4b71Sopenharmony_ci- On a One-time Basis 577e41f4b71Sopenharmony_ci 578e41f4b71Sopenharmony_ci To disable the transition animation for a single operation (implemented by APIs provided by **NavPathStack**, such as **Push**, **Pop**, and **Replace**), set the **animated** parameter in the API to **false**. This setting does not affect the next transition. 579e41f4b71Sopenharmony_ci ```ts 580e41f4b71Sopenharmony_ci pageStack: NavPathStack = new NavPathStack() 581e41f4b71Sopenharmony_ci 582e41f4b71Sopenharmony_ci this.pageStack.pushPath({ name: "PageOne" }, false) 583e41f4b71Sopenharmony_ci this.pageStack.pop(false) 584e41f4b71Sopenharmony_ci ``` 585e41f4b71Sopenharmony_ci 586e41f4b71Sopenharmony_ci### Customizing a Transition 587e41f4b71Sopenharmony_ci 588e41f4b71Sopenharmony_ciYou can customize transition animations through the [customNavContentTransition](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#customnavcontenttransition11) event. Specifically, you can define a custom transition animation in the following steps: 589e41f4b71Sopenharmony_ci 590e41f4b71Sopenharmony_ci1. Build a custom transition animation utility class **CustomNavigationUtils**, which manages custom transition animation **CustomTransition** objects for each page through a Map. A page registers its **CustomTransition** object when created and unregisters it when destroyed. 591e41f4b71Sopenharmony_ci2. Implement a transition protocol object [NavigationAnimatedTransition](..//reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#navigationanimatedtransition11). In this object, the **timeout** property indicates the timeout for the transition to end, with a default value of 1000 ms; the **transition** property is the custom transition animation API, where you should implement your own transition animation logic, which the system will call when the transition starts; **onTransitionEnd** is the callback when the transition ends. 592e41f4b71Sopenharmony_ci3. Call the **customNavContentTransition** API to return the **NavigationAnimatedTransition** object. If **undefined** is returned, the system default transition is used. 593e41f4b71Sopenharmony_ci 594e41f4b71Sopenharmony_ciFor details about the sample code, see [Example 3](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#example-3). 595e41f4b71Sopenharmony_ci 596e41f4b71Sopenharmony_ci### Defining a Shared Element Transition 597e41f4b71Sopenharmony_ci 598e41f4b71Sopenharmony_ciDuring the switching between **NavDestination** components, the [geometryTransition](../reference/apis-arkui/arkui-ts/ts-transition-animation-geometrytransition.md) API can be used to implement the shared element transitions. Pages configured with shared element transitions must have the system's default transition animations disabled. 599e41f4b71Sopenharmony_ci1. Add the **geometryTransition** attribute to the components that need to implement shared element transitions, ensuring that the **id** parameter is consistent between the two **NavDestination** components. 600e41f4b71Sopenharmony_ci 601e41f4b71Sopenharmony_ci ```ts 602e41f4b71Sopenharmony_ci // Set id of the source page. 603e41f4b71Sopenharmony_ci NavDestination() { 604e41f4b71Sopenharmony_ci Column() { 605e41f4b71Sopenharmony_ci ... 606e41f4b71Sopenharmony_ci Image($r('app.media.startIcon')) 607e41f4b71Sopenharmony_ci .geometryTransition('sharedId') 608e41f4b71Sopenharmony_ci .width(100) 609e41f4b71Sopenharmony_ci .height(100) 610e41f4b71Sopenharmony_ci } 611e41f4b71Sopenharmony_ci } 612e41f4b71Sopenharmony_ci .title('FromPage') 613e41f4b71Sopenharmony_ci 614e41f4b71Sopenharmony_ci // Set id of the destination page. 615e41f4b71Sopenharmony_ci NavDestination() { 616e41f4b71Sopenharmony_ci Column() { 617e41f4b71Sopenharmony_ci ... 618e41f4b71Sopenharmony_ci Image($r('app.media.startIcon')) 619e41f4b71Sopenharmony_ci .geometryTransition('sharedId') 620e41f4b71Sopenharmony_ci .width(200) 621e41f4b71Sopenharmony_ci .height(200) 622e41f4b71Sopenharmony_ci } 623e41f4b71Sopenharmony_ci } 624e41f4b71Sopenharmony_ci .title('ToPage') 625e41f4b71Sopenharmony_ci ``` 626e41f4b71Sopenharmony_ci 627e41f4b71Sopenharmony_ci2. Place the page routing operation in the **animateTo** animation closure, set the corresponding animation parameters, and disable the default transition. 628e41f4b71Sopenharmony_ci 629e41f4b71Sopenharmony_ci ```ts 630e41f4b71Sopenharmony_ci NavDestination() { 631e41f4b71Sopenharmony_ci Column() { 632e41f4b71Sopenharmony_ci Button('Go to Destination Page') 633e41f4b71Sopenharmony_ci .width('80%') 634e41f4b71Sopenharmony_ci .height(40) 635e41f4b71Sopenharmony_ci .margin(20) 636e41f4b71Sopenharmony_ci .onClick(() => { 637e41f4b71Sopenharmony_ci animateTo({ duration: 1000 }, () => { 638e41f4b71Sopenharmony_ci this.pageStack.pushPath({ name: 'ToPage' }, false) 639e41f4b71Sopenharmony_ci }) 640e41f4b71Sopenharmony_ci }) 641e41f4b71Sopenharmony_ci } 642e41f4b71Sopenharmony_ci } 643e41f4b71Sopenharmony_ci .title('FromPage') 644e41f4b71Sopenharmony_ci ``` 645e41f4b71Sopenharmony_ci 646e41f4b71Sopenharmony_ci## Cross-Package Dynamic Routing 647e41f4b71Sopenharmony_ci 648e41f4b71Sopenharmony_ciUsing static imports for page routing can lead to coupling between different modules and prolonged home page loading times. 649e41f4b71Sopenharmony_ci 650e41f4b71Sopenharmony_ciThe purpose of dynamic routing is to allow multiple modules (HARs/HSPs) to reuse the same business logic, with decoupling between different modules and integration of routing functionality. 651e41f4b71Sopenharmony_ci 652e41f4b71Sopenharmony_ci**Advantages of dynamic routing** 653e41f4b71Sopenharmony_ci 654e41f4b71Sopenharmony_ci- In addition to the URL for navigation, you can configure various information, such as the default orientation (landscape or portrait) and whether authentication is required. The configuration is processed in a unified manner during routing 655e41f4b71Sopenharmony_ci- You can assign a name to each routing page and navigate by name instead of file path. 656e41f4b71Sopenharmony_ci- Dynamic imports (on-demand loading) can be used to load pages to prevent the first page from loading a large amount of code, which can cause stuttering. 657e41f4b71Sopenharmony_ci 658e41f4b71Sopenharmony_ciDynamic routing provides two modes: [System Routing Table](#system-routing-table) and [Custom Routing Table](#custom-routing-table). 659e41f4b71Sopenharmony_ci 660e41f4b71Sopenharmony_ci- The system routing table is easier to use than the custom routing table. It only requires adding the corresponding page navigation configuration items to implement page navigation. 661e41f4b71Sopenharmony_ci 662e41f4b71Sopenharmony_ci- The custom route table is more complex to use, but can be customized to meet specific service requirements. 663e41f4b71Sopenharmony_ci 664e41f4b71Sopenharmony_ciThe custom route table and system route table can be used together. 665e41f4b71Sopenharmony_ci 666e41f4b71Sopenharmony_ci### System Routing Table 667e41f4b71Sopenharmony_ci 668e41f4b71Sopenharmony_ci**Navigation** supports the system routing table for dynamic routing since API version 12. Each service module (HSP/HAR) requires an individual **router_map.json** file. When routing is triggered, the application only needs to pass the name of the page that needs to be routed through the routing API provided by **NavPathStack**. In this case, the system will automatically complete the dynamic loading of the target module, page component construction, and route redirection. This way, module decoupling is achieved at the development level. The main steps are as follows: 669e41f4b71Sopenharmony_ci 670e41f4b71Sopenharmony_ci1. Add the route table configuration to the **module.json5** file of the redirection target module. 671e41f4b71Sopenharmony_ci 672e41f4b71Sopenharmony_ci ```json 673e41f4b71Sopenharmony_ci { 674e41f4b71Sopenharmony_ci "module" : { 675e41f4b71Sopenharmony_ci "routerMap": "$profile:route_map" 676e41f4b71Sopenharmony_ci } 677e41f4b71Sopenharmony_ci } 678e41f4b71Sopenharmony_ci ``` 679e41f4b71Sopenharmony_ci2. Create the **route_map.json** file in **resources/base/profile** of the project directory. Add the following configuration information: 680e41f4b71Sopenharmony_ci 681e41f4b71Sopenharmony_ci ```json 682e41f4b71Sopenharmony_ci { 683e41f4b71Sopenharmony_ci "routerMap": [ 684e41f4b71Sopenharmony_ci { 685e41f4b71Sopenharmony_ci "name": "PageOne", 686e41f4b71Sopenharmony_ci "pageSourceFile": "src/main/ets/pages/PageOne.ets", 687e41f4b71Sopenharmony_ci "buildFunction": "PageOneBuilder", 688e41f4b71Sopenharmony_ci "data": { 689e41f4b71Sopenharmony_ci "description" : "this is PageOne" 690e41f4b71Sopenharmony_ci } 691e41f4b71Sopenharmony_ci } 692e41f4b71Sopenharmony_ci ] 693e41f4b71Sopenharmony_ci } 694e41f4b71Sopenharmony_ci ``` 695e41f4b71Sopenharmony_ci 696e41f4b71Sopenharmony_ci The configuration is described as follows. 697e41f4b71Sopenharmony_ci 698e41f4b71Sopenharmony_ci | Item | Description | 699e41f4b71Sopenharmony_ci |---|---| 700e41f4b71Sopenharmony_ci | name | Name of the target page to be redirected to.| 701e41f4b71Sopenharmony_ci | pageSourceFile | Path of the target page in the package, relative to the **src** directory.| 702e41f4b71Sopenharmony_ci | buildFunction | Name of the entry point function for redirection to the target page, which must be decorated by @Builder. | 703e41f4b71Sopenharmony_ci | data | Custom data. You can obtain the value through the **getConfigInRouteMap** API.| 704e41f4b71Sopenharmony_ci 705e41f4b71Sopenharmony_ci3. On the target page, configure the @Builder decorated entry point function. The function name must be the same as the value of **buildFunction** in the **router_map.json** file. Otherwise, an error is reported at compile time. 706e41f4b71Sopenharmony_ci 707e41f4b71Sopenharmony_ci ```ts 708e41f4b71Sopenharmony_ci // Entry point function for redirection to the target page 709e41f4b71Sopenharmony_ci @Builder 710e41f4b71Sopenharmony_ci export function PageOneBuilder() { 711e41f4b71Sopenharmony_ci PageOne() 712e41f4b71Sopenharmony_ci } 713e41f4b71Sopenharmony_ci 714e41f4b71Sopenharmony_ci @Component 715e41f4b71Sopenharmony_ci struct PageOne { 716e41f4b71Sopenharmony_ci pathStack: NavPathStack = new NavPathStack() 717e41f4b71Sopenharmony_ci 718e41f4b71Sopenharmony_ci build() { 719e41f4b71Sopenharmony_ci NavDestination() { 720e41f4b71Sopenharmony_ci } 721e41f4b71Sopenharmony_ci .title('PageOne') 722e41f4b71Sopenharmony_ci .onReady((context: NavDestinationContext) => { 723e41f4b71Sopenharmony_ci this.pathStack = context.pathStack 724e41f4b71Sopenharmony_ci }) 725e41f4b71Sopenharmony_ci } 726e41f4b71Sopenharmony_ci } 727e41f4b71Sopenharmony_ci ``` 728e41f4b71Sopenharmony_ci4. Use routing APIs such as **pushPathByName** to navigate to the target page. (Note: In this case, you do not need to configure the **navDestination** attribute in **Navigation**.) 729e41f4b71Sopenharmony_ci 730e41f4b71Sopenharmony_ci ```ts 731e41f4b71Sopenharmony_ci @Entry 732e41f4b71Sopenharmony_ci @Component 733e41f4b71Sopenharmony_ci struct Index { 734e41f4b71Sopenharmony_ci pageStack : NavPathStack = new NavPathStack(); 735e41f4b71Sopenharmony_ci 736e41f4b71Sopenharmony_ci build() { 737e41f4b71Sopenharmony_ci Navigation(this.pageStack){ 738e41f4b71Sopenharmony_ci }.onAppear(() => { 739e41f4b71Sopenharmony_ci this.pageStack.pushPathByName("PageOne", null, false); 740e41f4b71Sopenharmony_ci }) 741e41f4b71Sopenharmony_ci .hideNavBar(true) 742e41f4b71Sopenharmony_ci } 743e41f4b71Sopenharmony_ci } 744e41f4b71Sopenharmony_ci ``` 745e41f4b71Sopenharmony_ci 746e41f4b71Sopenharmony_ci### Custom Routing Table 747e41f4b71Sopenharmony_ci 748e41f4b71Sopenharmony_ciYou can implement cross-package dynamic routing through a custom routing table. 749e41f4b71Sopenharmony_ci 750e41f4b71Sopenharmony_ci**Implementation:** 751e41f4b71Sopenharmony_ci 752e41f4b71Sopenharmony_ci1. Define page navigation configuration items. 753e41f4b71Sopenharmony_ci - Use resource files for definition. The [resource manager](../reference/apis-localization-kit/js-apis-resource-manager.md) parses resource files during running. 754e41f4b71Sopenharmony_ci - Configure the route loading configuration items in the .ets file, including the route page name (alias of the page in the **pushPath** API), name of the module where the file is located (name of the HSP/HAR module), and path of the page to be loaded in the module (relative to the **src** directory). 755e41f4b71Sopenharmony_ci2. Load the target navigation page. Use [import](../quick-start/arkts-dynamic-import.md) to load the module where the target page is located during running. After the module is loaded, call the method in the module, load the target page to be displayed in the module by importing the method of the module, and return the **Builder** function defined after the page is loaded. 756e41f4b71Sopenharmony_ci3. Trigger page navigation. Execute the **Builder** function loaded in step 2 in the [.navDestination](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#navdestination10) attribute of **Navigation** to navigate to the target page. 757e41f4b71Sopenharmony_ci<!--no_check-->