1. 程式人生 > 實用技巧 >Ionic4 5路由跳轉傳值複用詳細筆記

Ionic4 5路由跳轉傳值複用詳細筆記

1. 路由技術 ( 詳細記錄 )

是筆記不是博文,覺得寫的不夠詳細的可以使用Ctrl + W組合鍵

路由跳轉頁面

1. HTML 中使用 routerLink 屬性路由進行跳轉,傳值時使用 queryParams 屬性

<ion-item routerLink="/info1" [queryParams]="{name: '張'}">
    <ion-label>頁面跳轉</ion-label>
</ion-item>

2.1 通過 router 實現程式設計式導航以及攜帶引數 ( 官方推薦,我不推薦 ):

export class Tab1Page {
    constructor(public router: Router) {}
    openInfo1(){
        this.router.navigate(["info1"], {
            queryParams: {name: "張"}
        })
    }
}

2.2 通過 router 實現程式設計式導航以及攜帶引數:

export class Tab1Page {
    constructor(public router: Router) {}
    openInfo2(){
        this.router.navigate(["info1", {name: "張"}])
    }
}

3. 通過 NavController 實現程式設計式導航以及攜帶引數:

export class Tab1Page {
    constructor(public navCtrl: NavController) {}
    openInfo3(){
        this.navCtrl.navigateForward("info1", {
            queryParams: { name: "張" }
        })
    }
}

返回到上一頁面

1. HTML 中進行返回,slot 屬性為 start 時按鈕在左側,end 則在右側

<ion-header>
    <ion-toolbar>
        <!-- slot="end" -->
        <ion-buttons slot="start">
            <ion-back-button></ion-back-button>
        </ion-buttons>
        <ion-title>info1</ion-title>
    </ion-toolbar>
</ion-header>

2. 通過 router 程式設計式導航進行返回

export class Info1Page {
    constructor(public router: Router) { }
    back(){
        /*
         * 返回到指定頁面,嚴格點說是基於返回的動畫執行的開啟頁面的操作
         * 例如我從info1開啟info2,從info2中使用router.navigateByUrl返回到info1
         * 正常的返回什麼都不會發生,但是這種會重新觸發info1的生命週期函式
         */
        this.router.navigateByUrl("/tabs/tab1");
    }
}

3.1 通過 navController 程式設計式導航進行返回

export class Info1Page {
    constructor(public navCtrl: NavController) { }
    openInfo2(){
        this.navCtrl.navigateForward("info2")
    }
    back(){
        /*
         *  這種返回是基於路徑的歷史記錄進行返回的,他在後退的時候回根據上一個開啟的頁面進行返回
         *
         *  例如開啟info1,然後開啟info2,info2使用router.navigateByUrl進行返回,由於
         *  router.navigateByUrl是基於返回的動畫執行的開啟操作,所以info1使用nav.back進行
         *  返回的時候就會進入死迴圈,而且由於開啟順序的問題,動畫也會被改變
         */
        this.navCtrl.back();
    }
}

3.2 通過 navController 程式設計式導航進行返回

export class Info1Page {
    constructor(public navCtrl: NavController) { }
    openInfo2(){
        this.navCtrl.navigateForward("info2")
    }
    back(){
        /*
         *  pop不同於之前的函式,他是基於路由層級進行後退而不是基於歷史記錄進行後退
         *  可以說從根本上就可以解決 3.1 中出現的死迴圈問題
         */
        this.navCtrl.pop();
    }
}

接收路由傳參

路由的跳轉 ( 開啟以及返回 ) 基本已經掌握了,接下來開始學習獲取路由傳參的四種方法,路由傳參的方法有很多種,不同的傳參方式,接收的方法也不太相同,不過他們有一個共同點:使用的都是 ActivatedRoute

1.1 獲取路由傳參的第一種方式

export class Info1Page {
    constructor(public navCtrl: NavController, public navParam: ActivatedRoute) {
        navParam.queryParams.subscribe( param=>{
            console.log(param);
        })
        console.log("取值完畢!");
    }
}

這種方式是在 queryParams 中獲取路由攜帶引數,適用於之前提到路由傳參的【1】【2.1】【3】位置,但是這種獲取方式有一個問題,subscribe 是非同步的,也就是說 log("取值完畢!") 的執行會優先於 log( param ),這樣在獲取值後的操作就會顯得沒有那麼方便

1.2 獲取路由傳參的第一種方式 ( 同步 )

想要同步取值也不難,只需要改變一下程式碼:

export class Info1Page {
    constructor(public navCtrl: NavController, public navParam: ActivatedRoute) {
        // 通過 snapshot 就可以實現同步獲取
        console.log(navParam.snapshot.queryParams);
        console.log("取值完畢!");
    }
}

2.1 獲取路由傳參的第二種方式

export class Info1Page {
    constructor(public navCtrl: NavController, public navParam: ActivatedRoute) {
        navParam.params.subscribe( param=>{
            console.log(param);
        })
        console.log("取值完畢!");
    }
}

params 中也可以獲取路由攜帶引數,適用於之前提到路由傳參的【2.2】位置,同樣這種獲取方式還存在非同步問題,獲取值後的操作也沒那麼方便,解決方案也是一樣的

2.2 獲取路由傳參的第二種方式 ( 同步 )

export class Info1Page {
    constructor(public navCtrl: NavController, public navParam: ActivatedRoute) {
        // 通過 snapshot 就可以實現同步獲取
        console.log(navParam.snapshot.params);
        console.log("取值完畢!");
    }
}

實現頁面重複開啟

當我們在列表頁開啟一個詳細資訊頁面的時候,一般會傳遞一個 ID 在詳細資訊頁面進行查詢,如果我們在詳細資訊頁面同樣還要開啟一個詳細資訊頁面時,路由重複,這樣頁面就不會有任何操作,這裡推薦的解決方案是一種新的傳值方式

例如我要重複開啟 info1 頁面:

1. 首先在路由上動手腳:app-routing.module

const routes: Routes = [
    {
        path: '',
        loadChildren: () => import('./tabs/tabs.module').......省略
    },
    {
        path: 'info1',
        loadChildren: () => import('./info1/info1.module').......省略
    },
    // 新增這樣一個路由,代表接收變數名為time的值,以/的方式進行傳值
    {
        path: 'info1/:time',
        loadChildren: () => import('./info1/info1.module').......省略
    }
];

2. 然後在需要重複開啟的頁面中修改訪問路徑

export class Info1Page {
    constructor(public navCtrl: NavController) { }
    openInfo1(){
        // 在訪問路徑後面拼【接斜線+毫秒值】,使用毫秒值的原因就是防止值重複
        this.navCtrl.navigateForward("info1/" + new Date().getTime());
    }
}

最終訪問的路徑就變成了: http://localhost:4200/info1/1601452910158,可以解決重複訪問問題

上面的 1601452910158 毫秒值代表的就是 time 變數對應的值,這也屬於路由傳值的一種,如果想要在頁面上獲取到這串毫秒值可以使用路由接收傳參的【2.1】或【2.2】