1# Page Routing (router) 2 3 4Page routing refers to the redirection and data transfer between different pages in an application. In OpenHarmony, page routing can be implemented through APIs of the **Router** module. Through different URLs, you can easily navigate users through pages. This document describes the functions provided by the **Router** module from the following aspects: [Page Redirection](#page-redirection), [Page Return](#page-return), and [Adding a Confirmation Dialog Box Before Page Return](#adding-a-confirmation-dialog-box-before-page-return). 5 6 7## Page Redirection 8 9Page redirection is an important part of the development process. When using an application, you usually need to jump between different pages, and sometimes you need to pass data from one page to another. 10 11 **Figure 1** Page redirection 12 13 14The **Router** module provides two redirection modes: [router.pushUrl()](../reference/apis/js-apis-router.md#routerpushurl9) and [router.replaceUrl()](../reference/apis/js-apis-router.md#routerreplaceurl9). The two modes determine whether the target page will replace the current page. 15 16- **router.pushUrl()**: The target page does not replace the current page. Instead, it is pushed into the [page stack](../application-models/page-mission-stack.md). In this way, the state of the current page can be retained, and users can return to the current page by pressing the back button or calling the [router.back()](../reference/apis/js-apis-router.md#routerback) API. 17 18- **router.replaceUrl()**: The target page replaces the current page and destroys the current page. In this way, the resources of the current page can be released, and users cannot return to the current page. 19 20>**NOTE** 21> 22>The maximum capacity of a page stack is 32 pages. If this limit is exceeded, the [router.clear()](../reference/apis/js-apis-router.md#routerclear) API can be called to clear the historical page stack and free the memory. 23 24The **Router** module also provides two instance modes: **Standard** and **Single**. The two modes determine whether the target URL corresponds to multiple instances. 25 26- **Standard**: standard instance mode, which is the default instance mode. Each time this API is called, a target page is created and pushed to the top of the stack. 27 28- **Single**: singleton mode. If the URL of the target page already exists in the page stack, the page with the same URL closest to the top of the stack is moved to the top of the stack and reloaded. If the URL of the target page does not exist in the page stack, the page is redirected in standard mode. 29 30Before using the **Router** module, you need to import it to the code. 31 32 33```ts 34import router from '@ohos.router'; 35``` 36 37- Scenario 1: There is a home page (**Home**) and a details page (**Detail**). You want to click an offering on the home page to go to the details page. In addition, the home page needs to be retained in the page stack so that the status can be restored when the page is returned. In this scenario, you can use the **pushUrl()** API and use the **Standard** instance mode (which can also be omitted). 38 39 40 ```ts 41 // On the Home page 42 function onJumpClick(): void { 43 router.pushUrl({ 44 url: 'pages/Detail' // Target URL. 45 }, router.RouterMode.Standard, (err) => { 46 if (err) { 47 console.error(`Invoke pushUrl failed, code is ${err.code}, message is ${err.message}`); 48 return; 49 } 50 console.info('Invoke pushUrl succeeded.'); 51 }); 52 } 53 ``` 54 55 >**NOTE** 56 > 57 >In **Standard** instance mode, the **router.RouterMode.Standard** parameter can be omitted. 58 59- Scenario 2: There is a login page (**Login**) and a personal center page (**Profile**). After a user successfully logs in from the **Login** page, the **Profile** page is displayed. At the same time, the **Login** page is destroyed, and the application exits when the back button is pressed. In this scenario, you can use the **replaceUrl()** API and use the Standard instance mode (which can also be omitted). 60 61 62 ```ts 63 // On the Login page 64 function onJumpClick(): void { 65 router.replaceUrl({ 66 url: 'pages/Profile' // Target URL. 67 }, router.RouterMode.Standard, (err) => { 68 if (err) { 69 console.error(`Invoke replaceUrl failed, code is ${err.code}, message is ${err.message}`); 70 return; 71 } 72 console.info('Invoke replaceUrl succeeded.'); 73 }) 74 } 75 ``` 76 77 >**NOTE** 78 > 79 >In **Standard** instance mode, the **router.RouterMode.Standard** parameter can be omitted. 80 81- Scenario 3: There is a setting page (**Setting**) and a theme switching page (**Theme**). You want to click a theme option on the **Setting** page to go to the **Theme** page. In addition, you want to ensure that only one **Theme** page exists in the page stack at a time. When the back button is clicked on the **Theme** page, the **Setting** page is displayed. In this scenario, you can use the **pushUrl()** API and use the **Single** instance mode. 82 83 84 ```ts 85 // On the Setting page 86 function onJumpClick(): void { 87 router.pushUrl({ 88 url: 'pages/Theme' // Target URL. 89 }, router.RouterMode.Single, (err) => { 90 if (err) { 91 console.error(`Invoke pushUrl failed, code is ${err.code}, message is ${err.message}`); 92 return; 93 } 94 console.info('Invoke pushUrl succeeded.'); 95 }); 96 } 97 ``` 98 99- Scenario 4: There is a search result list page (**SearchResult**) and a search result details page (**SearchDetail**). You want to click a result on the **SearchResult** page to go to the **SearchDetail** page. In addition, if the result has been viewed before, clicking the result displays the existing details page, instead of creating a new one. In this scenario, you can use the **replaceUrl()** API and use the **Single** instance mode. 100 101 102 ```ts 103 // On the SearchResult page 104 function onJumpClick(): void { 105 router.replaceUrl({ 106 url: 'pages/SearchDetail' // Target URL. 107 }, router.RouterMode.Single, (err) => { 108 if (err) { 109 console.error(`Invoke replaceUrl failed, code is ${err.code}, message is ${err.message}`); 110 return; 111 } 112 console.info('Invoke replaceUrl succeeded.');}) 113 } 114 ``` 115 116The preceding scenarios do not involve parameter transfer. 117 118If you need to transfer some data to the target page during redirection, you can add a **params** attribute and specify an object as a parameter when invoking an API of the **Router** module. Example: 119 120 121```ts 122class DataModelInfo { 123 age: number; 124} 125 126class DataModel { 127 id: number; 128 info: DataModelInfo; 129} 130 131function onJumpClick(): void { 132 // On the Home page 133 let paramsInfo: DataModel = { 134 id: 123, 135 info: { 136 age: 20 137 } 138 }; 139 140 router.pushUrl({ 141 url: 'pages/Detail', // Target URL. 142 params: paramsInfo // Add the params attribute to transfer custom parameters. 143 }, (err) => { 144 if (err) { 145 console.error(`Invoke pushUrl failed, code is ${err.code}, message is ${err.message}`); 146 return; 147 } 148 console.info('Invoke pushUrl succeeded.'); 149 }) 150} 151``` 152 153On the target page, you can call the [getParams()](../reference/apis/js-apis-router.md#routergetparams) API of the **Router** module to obtain the transferred parameters. Example: 154 155 156```ts 157const params = router.getParams(); // Obtain the transferred parameter object. 158const id = params['id']; // Obtain the value of the id attribute. 159const age = params['info'].age; // Obtain the value of the age attribute. 160``` 161 162 163## Page Return 164 165After a user completes an operation on a page, the user usually needs to return to the previous page or a specified page. In this case, the page return function is required. During the return process, the data may need to be transferred to the target page, which requires the data transfer function. 166 167 **Figure 2** Page return 168 169 170 171Before using the **Router** module, you need to import it to the code. 172 173 174```ts 175import router from '@ohos.router'; 176``` 177 178You can use any of the following methods to return to a page: 179 180- Method 1: Return to the previous page. 181 182 183 ```ts 184 router.back(); 185 ``` 186 187 This method allows you to return to the position of the previous page in the page stack. For this method to work, the previous page must exist in the page stack. 188 189- Method 2: Return to the specified page. 190 191 192 ```ts 193 router.back({ 194 url: 'pages/Home' 195 }); 196 ``` 197 198 This method allows you to return to a specified page. You need to specify the path of the target page. For this method to work, the target page must it exist in the page stack. 199 200- Method 3: Return to the specified page and transfer custom parameter information. 201 202 203 ```ts 204 router.back({ 205 url: 'pages/Home', 206 params: { 207 info:'From Home Page' 208 } 209 }); 210 ``` 211 212 This method not only allows you to return to the specified page, but also transfer custom parameter information when returning. The parameter information can be obtained and parsed by invoking the **router.getParams()** API on the target page. 213 214On the target page, call the **router.getParams()** API at the position where parameters need to be obtained, for example, in the **onPageShow()** lifecycle callback: 215 216 217```ts 218onPageShow() { 219 const params = router.getParams(); // Obtain the transferred parameter object. 220 const info = params['info']; // Obtain the value of the info attribute. 221} 222``` 223 224>**NOTE** 225> 226>When the **router.back()** API is used to return to a specified page, the page is pushed to the top of the stack again, and all page stacks between the original top page (included) and the specified page (excluded) are destroyed. 227> 228> If the **router.back()** method is used to return to the original page, the original page will not be created repeatedly. Therefore, the variable declared using \@State will not be declared repeatedly, and the **aboutToAppear()** lifecycle callback of the page will not be triggered. If you want to use the custom parameters transferred from the returned page on the original page, you can parse the parameters in the required position. For example, parameter parsing can be performed in the **onPageShow()** lifecycle callback. 229 230 231## Adding a Confirmation Dialog Box Before Page Return 232 233During application development, to prevent misoperations or data loss, a dialog box needs to be displayed before a user returns from one page to another, asking the user whether to perform the operation. 234 235Such a dialog box can be in the [default style](#default-confirmation-dialog-box) or [custom style](#custom-confirmation-dialog-box). 236 237 **Figure 3** Adding a confirmation dialog box before page return 238 239 240 241 242### Default Confirmation Dialog Box 243 244To implement this function, you can use the [router.showAlertBeforeBackPage()](../reference/apis/js-apis-router.md#routershowalertbeforebackpage9) and [router.back()](../reference/apis/js-apis-router.md#routerback) APIs provided by the **Router** module. 245 246Before using the **Router** module, you need to import it to the code. 247 248 249```ts 250import router from '@ohos.router'; 251``` 252 253To enable the confirmation dialog box for page return, call the [router.showAlertBeforeBackPage()](../reference/apis/js-apis-router.md#routershowalertbeforebackpage9) API (for setting the information about the dialog box), then the [router.back()](../reference/apis/js-apis-router.md#routerback) API. For example, define a click event processing function for the back button on the payment page: 254 255 256```ts 257// Define a click event processing function for the back button. 258function onBackClick(): void { 259 // Invoke the router.showAlertBeforeBackPage() API to set the information about the confirmation dialog box. 260 try { 261 router.showAlertBeforeBackPage({ 262 message: 'Payment not completed yet. Are you sure you want to return?' // Set the content of the confirmation dialog box. 263 }); 264 } catch (err) { 265 console.error(`Invoke showAlertBeforeBackPage failed, code is ${err.code}, message is ${err.message}`); 266 } 267 268 // Invoke the router.back() API to return to the previous page. 269 router.back(); 270} 271``` 272 273The **router.showAlertBeforeBackPage()** API receives an object as a parameter. The object contains the following attributes: 274 275- **message**: content of the dialog box. The value is of the string type. 276 If the API is successfully called, the confirmation dialog box is displayed on the target page. Otherwise, an exception is thrown and the error code and error information is obtained through **err.code** and **err.message**. 277 278 When the user clicks the back button, a confirmation dialog box is displayed, prompting the user to confirm their operation. If the user selects Cancel, the application stays on the current page. If the user selects OK, the **router.back()** API is triggered and the redirection is performed based on the parameters. 279 280 281### Custom Confirmation Dialog Box 282 283To implement a custom confirmation dialog box, use APIs in the [PromptAction](../reference/apis/js-apis-promptAction.md#promptactionshowdialog) module or customize a popup window. This topic uses the APIs in the **PromptAction** module an example to describe how to implement a custom confirmation dialog box. 284 285Before using the **Router** module, you need to import it to the code. 286 287 288```ts 289import router from '@ohos.router'; 290``` 291 292In the event callback, call the [promptAction.showDialog()](../reference/apis/js-apis-promptAction.md#promptactionshowdialog) API of the **PromptAction** module. 293 294 295```ts 296function onBackClick() { 297 // Display a custom confirmation dialog box. 298 promptAction.showDialog({ 299 message:'Payment not completed yet. Are you sure you want to return?', 300 buttons: [ 301 { 302 text: 'Cancel', 303 color: '#FF0000' 304 }, 305 { 306 text: 'OK', 307 color: '#0099FF' 308 } 309 ] 310 }).then((result) => { 311 if (result.index === 0) { 312 // The user selects Cancel. 313 console.info('User canceled the operation.'); 314 } else if (result.index === 1) { 315 // The user selects OK. 316 console.info('User confirmed the operation.'); 317 // Invoke the router.back() API to return to the previous page. 318 router.back(); 319 } 320 }).catch((err) => { 321 console.error(`Invoke showDialog failed, code is ${err.code}, message is ${err.message}`); 322 }) 323} 324``` 325 326When the user clicks the back button, the custom confirmation dialog box is displayed, prompting the user to confirm their operation. If the user selects Cancel, the application stays on the current page. If the user selects OK, the **router.back()** API is triggered and the redirection is performed based on the parameters. 327