Ionic5路由跳转传值复用


1. 路由技术 ( 详细记录 )

是笔记不是博文,觉得写的不够详细的可以使用Ctrl + W组合键

路由跳转页面

1. HTML 中使用 routerLink 属性路由进行跳转,传值时使用 queryParams 属性


    页面跳转

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 则在右侧


    
        
        
            
        
        info1
    

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】