文章目錄
- 一、前言
- 二、頁面跳轉
- 三、頁面返回
- 四、頁面返回前增加確認對話框
- 4.1 系統的默認詢問框
- 4.2 自定義詢問框
- 五、拓展閱讀
一、前言
APP開發過程中,多頁面跳轉場景十分常見,例如,登錄 -> 首頁 -> 個人中心。在鴻蒙開發中,頁面間的跳轉被稱作為“頁面路由”。
HarmonyOS
提供了Router
模塊,通過不同的url
地址,可以方便地進行頁面路由,輕松地訪問不同的頁面。
二、頁面跳轉
頁面跳轉是開發過程中的一個重要組成部分。在使用應用程序時,通常需要在不同的頁面之間跳轉,有時還需要將數據從一個頁面傳遞到另一個頁面。下面是一個頁面跳轉的簡單示例:
Router
模塊提供了兩種跳轉模式,分別是router.pushUrl()
和router.replaceUrl()
。這兩種模式決定了目標頁是否會替換當前頁。
-
router.pushUrl()
:目標頁不會替換當前頁,而是壓入頁面棧。這樣可以保留當前頁的狀態,并且可以通過返回鍵或者調用router.back()
方法返回到當前頁。 -
router.replaceUrl()
:目標頁會替換當前頁,并銷毀當前頁。這樣可以釋放當前頁的資源,并且無法返回到當前頁。
需要注意的是:頁面棧的最大容量為 32 個頁面。如果超過這個限制,可以調用router.clear()
方法清空歷史頁面棧,釋放內存空間。
另外,Router
模塊提供了兩種實例模式,分別是Standard
和Single
。這兩種模式決定了目標url
是否會對應多個實例。
-
Standard
:標準實例模式,也是默認情況下的實例模式。每次調用該方法都會新建一個目標頁,并壓入棧頂。 -
Single
:單實例模式。即如果目標頁的url
在頁面棧中已經存在同url
頁面,則離棧頂最近的同url
頁面會被移動到棧頂,并重新加載;如果目標頁的url
在頁面棧中不存在同url
頁面,則按照標準模式跳轉。
在使用頁面路由Router
相關功能之前,需要在代碼中先導入Router模塊。
import router from '@ohos.router';
示例場景一:有一個主頁(Home)和一個詳情頁(Detail),希望從主頁點擊一個商品,跳轉到詳情頁。同時,需要保留主頁在頁面棧中,以便返回時恢復狀態。這種場景下,可以使用pushUrl()
方法,并且使用Standard
實例模式(或者省略)。
// 在Home頁面中
function onJumpClick(): void {router.pushUrl({url: 'pages/Detail' // 目標url}, router.RouterMode.Standard, (err) => {if (err) {console.error(`Invoke pushUrl failed, code is ${err.code}, message is ${err.message}`);return;}console.info('Invoke pushUrl succeeded.');});
}
示例場景二:有一個登錄頁(Login)和一個個人中心頁(Profile),希望從登錄頁成功登錄后,跳轉到個人中心頁。同時,銷毀登錄頁,在返回時直接退出應用。這種場景下,可以使用replaceUrl()
方法,并且使用Standard
實例模式(或者省略)。
// 在Login頁面中
function onJumpClick(): void {router.replaceUrl({url: 'pages/Profile' // 目標url}, router.RouterMode.Standard, (err) => {if (err) {console.error(`Invoke replaceUrl failed, code is ${err.code}, message is ${err.message}`);return;}console.info('Invoke replaceUrl succeeded.');})
}
示例場景三:有一個設置頁(Setting)和一個主題切換頁(Theme),希望從設置頁點擊主題選項,跳轉到主題切換頁。同時,需要保證每次只有一個主題切換頁存在于頁面棧中,在返回時直接回到設置頁。這種場景下,可以使用pushUrl()
方法,并且使用Single
實例模式。
// 在Setting頁面中
function onJumpClick(): void {router.pushUrl({url: 'pages/Theme' // 目標url}, router.RouterMode.Single, (err) => {if (err) {console.error(`Invoke pushUrl failed, code is ${err.code}, message is ${err.message}`);return;}console.info('Invoke pushUrl succeeded.');});
}
示例場景四:有一個搜索結果列表頁(SearchResult)和一個搜索結果詳情頁(SearchDetail),希望從搜索結果列表頁點擊某一項結果,跳轉到搜索結果詳情頁。同時,如果該結果已經被查看過,則不需要再新建一個詳情頁,而是直接跳轉到已經存在的詳情頁。這種場景下,可以使用replaceUrl()
方法,并且使用Single
實例模式。
// 在SearchResult頁面中
function onJumpClick(): void {router.replaceUrl({url: 'pages/SearchDetail' // 目標url}, router.RouterMode.Single, (err) => {if (err) {console.error(`Invoke replaceUrl failed, code is ${err.code}, message is ${err.message}`);return;}console.info('Invoke replaceUrl succeeded.');})
}
以上討論的場景都是直接跳轉的場景,頁面之間并沒有實現數據傳遞。
如果頁面間需要在跳轉時傳遞數據至目標頁,則可以在調用Router
模塊的方法時,添加param
屬性,并指定一個對象為參數,例如:
class DataModelInfo {age: number;
}
class DataModel {id: number;info: DataModelInfo;
}
function onJumpClick(): void {// 在Home頁面中let paramsInfo: DataModel = {id: 123,info: {age: 20}};router.pushUrl({url: 'pages/Detail', // 目標urlparams: paramsInfo // 添加params屬性,傳遞自定義參數}, (err) => {if (err) {console.error(`Invoke pushUrl failed, code is ${err.code}, message is ${err.message}`);return;}console.info('Invoke pushUrl succeeded.');})
}
在目標頁中,可以通過調用Router
模塊的getParams()
方法來獲取傳遞過來的參數。例如:
const params = router.getParams(); // 獲取傳遞過來的參數對象
const id = params['id']; // 獲取id屬性的值
const age = params['info'].age; // 獲取age屬性的值
三、頁面返回
當用戶在一個頁面完成操作后,通常需要返回到上一個頁面或者指定頁面,這就需要用到頁面返回功能。在返回的過程中,可能需要將數據傳遞給目標頁,這就需要用到數據傳遞功能。
與頁面跳轉類似,在使用頁面路由Router
相關功能之前,需要在代碼中先導入Router
模塊。
import router from '@ohos.router';
示例場景一:直接返回到上一個頁面,那實現代碼則可以是:
router.back();
這種方式會返回到上一個頁面,即上一個頁面在頁面棧中的位置。但是,上一個頁面必須存在于頁面棧中才能夠返回,否則該方法將無效。
示例場景二:返回到指定的頁面
router.back({url: 'pages/Home'
});
這種方式可以返回到指定頁面,需要指定目標頁的路徑。目標頁必須存在于頁面棧中才能夠返回。
示例場景三:返回到指定頁面,并傳遞自定義參數信息。
router.back({url: 'pages/Home',params: {info: '來自Home頁'}
});
這種方式不僅可以返回到指定頁面,還可以在返回的同時傳遞自定義參數信息。這些參數信息可以在目標頁中通過調用router.getParams()
方法進行獲取和解析。
如果返回時傳遞了自定義參數到返回的頁面,那返回的目標怎么獲取傳遞過來的參數呢?
在目標頁中,在需要獲取參數的位置調用router.getParams()
方法即可,例如在onPageShow()
生命周期回調中:
onPageShow() {const params = router.getParams(); // 獲取傳遞過來的參數對象const info = params['info']; // 獲取info屬性的值
}
注意??: 當使用router.back()
方法返回到指定頁面時,原棧頂頁面(包括)到指定頁面(不包括)之間的所有頁面棧都將從棧中彈出并銷毀。
另外,如果使用router.back()
方法返回到原來的頁面,原頁面不會被重復創建,因此使用@State
聲明的變量不會重復聲明,也不會觸發頁面的aboutToAppear()
生命周期回調。如果需要在原頁面中使用返回頁面傳遞的自定義參數,可以在需要的位置進行參數解析。例如,在onPageShow()
生命周期回調中進行參數解析。
四、頁面返回前增加確認對話框
在開發應用時,為了避免用戶誤操作或者丟失數據,有時候需要在用戶從一個頁面返回到另一個頁面之前,彈出一個詢問框,讓用戶確認是否要執行這個操作。
接下來將從系統默認詢問框和自定義詢問框兩個方面來介紹如何實現頁面返回前增加一個詢問框的功能。
4.1 系統的默認詢問框
為了實現這個功能,可以使用頁面路由Router
模塊提供的兩個方法:router.showAlertBeforeBackPage()
和router.back()
來實現這個功能。具體怎么做呢?
import router from '@ohos.router';
實現默認詢問框,代碼如下:???????
// 定義一個返回按鈕的點擊事件處理函數
function onBackClick(): void {// 調用router.showAlertBeforeBackPage()方法,設置返回詢問框的信息try {router.showAlertBeforeBackPage({message: '您還沒有完成點贊關注,確定要返回嗎?' // 設置詢問框的內容});} catch (err) {console.error(`Invoke showAlertBeforeBackPage failed, code is ${err.code}, message is ${err.message}`);}// 調用router.back()方法,返回上一個頁面router.back();
}
其中,router.showAlertBeforeBackPage()
方法接收一個對象作為參數,該對象包含以下屬性:
message
:string
類型,表示詢問框的內容。
如果調用成功,則會在目標界面開啟頁面返回詢問框;如果調用失敗,則會拋出異常,并通過err.code
和err.message
獲取錯誤碼和錯誤信息。
當用戶點擊“返回”按鈕時,會彈出確認對話框,詢問用戶是否確認返回。選擇“取消”將停留在當前頁目標頁;選擇“確認”將觸發router.back()
方法,并根據參數決定如何執行跳轉。
4.2 自定義詢問框
自定義詢問框的方式,可以使用彈窗或者自定義彈窗實現。這樣可以讓應用界面與系統默認詢問框有所區別,提高應用的用戶體驗度。本文以彈窗為例,介紹如何實現自定義詢問框。
在事件回調中,調用彈窗的promptAction.showDialog()
方法:???????
import router from '@ohos.router';
import promptAction from '@ohos.promptAction';
@Entry
@Component
struct SecondPage {@State message: string = 'Hello World'onBackPress() {// 彈出自定義的詢問框promptAction.showDialog({message: '您還沒有完成點贊關注,確定要返回嗎?',buttons: [{text: '取消',color: '#FF0000'},{text: '確認',color: '#0099FF'}]}).then((result) => {if (result.index === 0) {// 用戶點擊了“取消”按鈕console.info('User canceled the operation.');} else if (result.index === 1) {// 用戶點擊了“確認”按鈕console.info('User confirmed the operation.');// 調用router.back()方法,返回上一個頁面router.back();}}).catch((err) => {console.error(`Invoke showDialog failed, code is ${err.code}, message is ${err.message}`);})return true;}build() {Row() {Column() {Text(this.message).fontSize(50).fontWeight(FontWeight.Bold)}.width('100%')}.height('100%')}
}
當用戶點擊“返回”按鈕時,會彈出自定義的詢問框,詢問用戶是否確認返回。選擇“取消”將停留在當前頁目標頁;選擇“確認”將觸發router.back()
方法,并根據參數決定如何執行跳轉。
示意效果如下:
注??:路由跳轉中的url
維護在profile/main_pages.json
中。
五、拓展閱讀
- 《鴻蒙官網》
- 《API參考》