5. 路由
1.頁面路由(router模式)
1.概述
頁面路由指的是在應用程序中實現不同頁面之間的跳轉,以及數據傳遞。
我們先明確自定義組件和頁面的關系:
- 自定義組件:@Component 裝飾的UI單元,
- 頁面:即應用的UI頁面。可以由一個或者多個自定義組件組成。
-
- @Entry裝飾的自定義組件為頁面的入口組件,即頁面的根節點,一個頁面有且僅能有一個@Entry
通過 Router 模塊就可以實現這個功能. import { router } from '@kit.ArkUI'
步驟:
- 創建頁面 -> 頁面與組件不同的地方是有且只有一個入口組件( @Entry修飾),并且在
src/main/resources/base/profile/main_pages.json
有配置好了頁面路徑
-
- 口訣:一入口,一配置
- router控制頁面跳轉
- 帶參數跳轉并獲取
2.pushUrl 與 replaceUrl
先來看看 pushUrl的情況
- 默認打開首頁 → 首頁入棧
- pushUrl 去詳情頁 → 詳情頁入棧
- back 返回上一頁 → 詳情頁出棧
- 此時頁面棧中應該只有一個頁面
整一個過程中,都可以 router.getLength 進行查看
再來看看replaceUrl的情況
- 默認打開首頁 → 首頁入棧
- replaceUrl 去詳情頁 → 詳情頁替換首頁,首頁銷毀
- back 無法返回 → 沒有上一頁
跳轉到登錄頁面時可以使用 replaceUrl,因為無需在頁面棧中保存其他頁面的頁面棧信息了。
頁面棧相關 api
// 獲取頁面棧長度router.getLength()// 獲取頁面狀態let page = router.getState();console.log('頁面棧數量:' + page.index);console.log('跳轉的路由:' + page.name);console.log('路由路徑:' + page.path);// 清空頁面棧// router.clear()
3.路由模式
路由提供了兩種不同的跳轉模式:
- standard(標準實例模式)
- Single(單實例模式)
不同模式的決定了頁面是否會創建多個實例:
- Standard:無論之前是否添加過,一直添加到頁面棧【默認】
-
- 場景:適用于每次跳轉都呈現全新內容或狀態的場景,避免數據展示紊亂(數據變化)
- Single:如果之前加過頁面,會使用之前添加的頁面【需要添加參數手動修改】
-
- 場景:適用于那些需要保留頁面狀態或避免重復創建相同頁面的場景(數據不變化)
路由模式語法:
總結
路由跳轉的方式有pushUrl和replaceUrl
pushUrl的跳轉要考慮兩種模式:標準模式,單例模式
- pushUrl({},模式為標準模式(默認的模式)) -> 頁面棧中的表現形式
- pushUrl({},模式為單例模式) -> 頁面棧中的表現形式
- replaceUrl() -> 跳轉以后的前一個頁面自動銷毀了
2.Navigation 路由
概述
組件導航(Navigation)主要用于實現頁面間以及組件內部的頁面跳轉,支持在不同組件間傳遞跳轉參數,提供靈活的跳轉棧操作,從而更便捷地實現對不同頁面的訪問和復用。本文將從組件導航(Navigation)的顯示模式、路由操作、子頁面管理、跨包跳轉以及跳轉動效等幾個方面進行詳細介紹。
Navigation是路由導航的根視圖容器,一般作為頁面(@Entry)的根容器,包括單欄(Stack)、分欄(Split)和自適應(Auto)三種顯示模式。Navigation組件適用于模塊內和跨模塊的路由切換,通過組件級路由能力實現更加自然流暢的轉場體驗,并提供多種標題欄樣式來呈現更好的標題和內容聯動效果。一次開發,多端部署場景下,Navigation組件能夠自動適配窗口顯示大小,在窗口較大的場景下自動切換分欄展示效果。
Navigation組件主要包含導航頁和子頁。導航頁由標題欄(包含菜單欄)、內容區和工具欄組成,可以通過hideNavBar屬性進行隱藏,導航頁不存在頁面棧中,與子頁,以及子頁之間可以通過路由操作進行切換。
1.是什么
Navigation是華為HarmonyOS中的一個路由導航組件,主要用于實現頁面間的跳轉和路由管理。它提供了豐富的功能和靈活的配置選項,支持模塊內和跨模塊的路由切換。Navigation組件不僅簡化了路由切換的邏輯,還提升了應用的導航效率和用戶體驗。
2. 為什么
- 1.簡化路由管理:Navigation通過組件級的路由能力,簡化了頁面間的跳轉邏輯,使得路由管理更加直觀和便捷。
- 2.支持模塊化開發:Navigation支持模塊內和跨模塊的路由切換,有助于實現模塊間的解耦,提升代碼的可維護性和可擴展性。
- 3.豐富的動效支持:Navigation提供了豐富的轉場動畫和共享元素轉場能力,增強了頁面切換的視覺效果。
- 4.生命周期管理:Navigation支持頁面生命周期的監聽和管理,開發者可以更方便地處理頁面的顯示和隱藏等狀態變化。
- 5.動態路由:Navigation支持動態路由,允許在運行時動態加載和注冊路由,提升了路由管理的靈活性。
3.怎么用
// 1.全局聲明一個路徑棧
export const pathStack = new NavPathStack()
//路由攔截
pathStack.setInterception({willShow: (from: NavDestinationContext | "navBar", to: NavDestinationContext | "navBar",operation: NavigationOperation, animated: boolean) => {if (typeof to === "string") {AlertDialog.show({ message:JSON.stringify('回到了首頁',null,2) })return;}// 將跳轉到Page1的路由重定向到page2let target: NavDestinationContext = to as NavDestinationContext;AlertDialog.show({ message:JSON.stringify(target,null,2) })if (target.pathInfo.name === 'page1') {// target.pathStack.pop();// target.pathStack.pushPathByName('page2', null);}}
})
import { pathStack } from './utils/pathStack';@Entry
@Component
struct Demo {
param: Record<string, string> = {'name':'zs'};build() {// 2.使用頁面棧Navigation(pathStack) {Button('跳轉到page1').margin({bottom:10}).onClick(() => {// 頁面跳轉pathStack.pushPathByName('page1',null)})Button('跳轉到page2').onClick(() => {// 頁面跳轉pathStack.pushPathByName('page2',this.param)})}.title('My Page');}
}
{"routerMap": [{"name": "page1","pageSourceFile": "src/main/ets/pages/page1.ets","buildFunction": "MyPage1","data": {"description": "這是頁面1"}},{"name": "page2","pageSourceFile": "src/main/ets/pages/page2.ets","buildFunction": "MyPage2","data": {"description": "這是頁面2"}}]
}
import { pathStack } from './utils/pathStack'@Builderfunction MyPage1() {page1()}@Componentstruct page1 {build() {//3.子頁面必須要使用 NavDestination 把所有結構都包起來NavDestination() {Column() {Button('回到上一頁').onClick(() => {pathStack.pop()})}.width("100%").height("100%").justifyContent(FlexAlign.Center)}.title('page1')}}
import { pathStack } from './utils/pathStack'@Builder
function MyPage2() {page2()
}@Component
struct page2 {@State param: Record<string, string> = {};
aboutToAppear(): void {// AlertDialog.show({ message:JSON.stringify(pathStack.getParamByName('page2'),null,2) })// 獲取page2頁面的參數this.param = pathStack.getParamByName('page2').pop() as Record<string, string>;}build() {//2.子頁面必須要使用 NavDestination 把所有結構都包起來NavDestination() {Column({space:5}) {Text(`你好${this.param?.name}`)Button('回到上一頁').onClick(() => {pathStack.pop()})Button('回到首頁').onClick(() => {// 返回到根首頁(清除棧中所有頁面)pathStack.clear()})Button('去往page1').onClick(() => {// 返回到根首頁(清除棧中所有頁面)pathStack.pushPathByName('page1',null)})}.width("100%").height("100%").justifyContent(FlexAlign.Center)}}
}
?