前言
- 由于angular官网路由与导航章节介绍的内容太多、太复杂,本文本着实用的目的介绍angular路由的常用配置及导航传参
- 阅读本文前,建议先阅读[ionic官网路由与导航内容
路由配置
- 常见的路由配置如下代码,配置说明看代码上的注释,后面还有重难点说明
import { RouterModule } from '@angular/router';
@NgModule({
imports: [
...
RouterModule.forRoot([
// 若app启动地址为http://localhost:8100/,则访问LoginPage
{ path: '', component: LoginPage },
// 访问http://localhost:8100/main,则跳转至mainPage
{ path: 'main', component: mainPage },
// loadChildren懒加载,参数值是相对模块文件所在路径
// 访问http://localhost:8100/register,才去加载资源
// 建议app一级页面使用component,二级页面均使用loadChildren
{path: 'register', loadChildren: './pages/login/register/register.module#RegisterPageModule'}
// 访问http://localhost:8100/detail/2,则访问DetailPage,id为动态参数
{path: 'detail/:id', component: DetailPage },
// 访问main/666重定向到mainPage
{path: 'main/666', redirectTo: '/main', pathMatch: 'full' },
// pathMatch: 'prefix',访问main/666、main/xxx、main/abc,均跳转到mainPage
{path: 'main', redirectTo: '/main', pathMatch: 'prefix' },
// 路径匹配不到则访问NotFoundPage
{path: '**', component: NotFoundPage },
// children(父子路由配置)
// 访问/tabs跳转到TabsPage,TabsPage只是一个底部导航。也相当于web网站的顶部导航或左侧导航
// 所以需要访问/tabs/demo,才会显示导航和内容
// 访问/tabs/tab1/test,显示导航和testPage,test模块使用loadChildren懒加载
{
path: 'tabs',
component: TabsPage,
children: [
{path: 'demo', component: DemoPage},
{path: 'tab1', component: Tab1Page},
{path: 'tab1/test', loadChildren: './pages/tab1/test/test.module#TestPageModule'},
{path: 'mine', component: MinePage}
]
}
])
],
})
- 使用
component
,需要在对应的模块declarations
中声明组件
- 使用
loadChildren
加载子模块,路径是相对相对路径,相对于父模块文件所在路径;什么时候会用loadChildren
配置?
在web端界面一般顶部或左侧有导航,下面或右侧显示内容,在app端一般底部有tab导航,上面显示内容;如下配置,TabsPage
就是导航界面,children
配置内容界面路由
{
path: 'tabs',
component: TabsPage,
children: [
{path: 'demo', component: DemoPage},
{path: 'mine', component: MinePage}
]
}
- 根模块是
forRoot
子模块是forChild
,如下图所示
- 建议app一级页面使用
component
配置,二级页面使用loadChildren
,如下图是我的路由配置,TabsPage
是导航页面,Tab1Page、DemoPage、MinePage
是一级页面,其余是二级页面
考虑多人开发,若同时修改一份路由文件,会经常冲突,所以按业务分类多个配置文件,所以下图出现...tab1Routes、...demoRoutes、 ...mineRoutes
,完整代码点这里
-
redirectTo
重定向有个坑,假如配置如下,由于TabPage
使用component
配置,则应用启动时就会加载TabPage
,当你后来导航到/test
,则会重定向到TabPage
,此时TabPage
就会初始化第二次,如果你在constructor()
中对全局对象做过修改那就回修改第二次
我当时在tabs.page.ts文件中订阅android返回按钮事件,就订阅了两次,而且只能在真机调试中发现,坑很深
const routes: Routes = [
{path: 'test', redirectTo: 'tab', pathMatch: 'full' },
{path: 'tab', component: TabPage}
];
- 刚开始对路由配置不熟悉,应尽量避免使用
path: ''
配置,尤其类似下面的重定向,要不然会让你懵逼
{ path: '', redirectTo: '/path', pathMatch: 'full'}
如下gif图,从tab2跳转到test页面,点击返回,竟然返回到了tab1页面,如下图2注释默认生成的path: ''
路由即可
- 如下图红色框内代码,是给页面动态添加返回按钮,当页面是根页面时,返回按钮不显示;当
ion-back-button
添加defaultHref
属性后,即使是根页面或按F5刷新页面也会显示返回按钮,点击返回按钮返回到指定页面
<ion-buttons slot="start">
<ion-back-button defaultHref="/tabs/tab1"></ion-back-button>
</ion-buttons>
导航
一
- 如下是最基本的路由配置
{ path: 'main', component: mainPage }
- 在html中和ts中导航到mainPage 方法如下
<ion-button routerLink="/main">next page</ion-button>
<ion-button [routerLink]="['/main']">next page</ion-button>
constructor(public router: Router, public nav: NavController) {}
next() {
this.router.navigateByUrl('/main');
this.router.navigate(['/main']);
this.nav.navigateForward('/main');
}
- 返回方式如下。返回和上面的“navigate”方法动画是不一样的
goBack() {
this.nav.pop(); // 返回到上一个页面
this.nav.back(); // 同上
this.nav.navigateBack('/'); // 可以指定返回的页面路径
}
二
- 如下是url带参数的路由配置
{path: 'detail/:id', component: DetailPage }
- 在html中和ts中导航到DetailPage 方法如下,注意参数是在数组内,不是方法内
<ion-button [routerLink]="['/detail', 6]">next page</ion-button>
constructor(public router: Router) {}
next() {
this.router.navigate(['/detail, 6']);
}
- 接收url参数两种方法,注意这里用的是
ActivatedRoute
不是Router
constructor(private route: ActivatedRoute) {
const params = this.route.snapshot.params;
console.log(params.id);
this.route.params.subscribe(res => {
console.log(res.id);
});
}
三
- 导航传递对象参数
this.router.navigateByUrl('/main?page=1&size=10');
this.router.navigate(['/main'], {queryParams: {page: 1, size: 10}});
注意这样传参是接收不到的
this.nav.navigateByUrl('/main', {queryParams: {page: 1, size: 10}});
- 接收参数两种方法
constructor(private route: ActivatedRoute) {
const queryParams = this.route.snapshot.queryParams;
console.log(queryParams);
this.route.queryParams.subscribe(res => {
console.log(res);
});
}
- 还有其他传递参数的方法。如发布订阅事件,使用Service,全局对象,本地存储等
其他
- 默认情况下,应用登录成功后跳转到主页,这时候点击返回按钮又返回到登录页,这是不科学的。所以需要使用如下
NavController.navigateRoot
方法设置主页面为顶层页面
constructor(public nav: NavController) {}
login() {
this.nav.navigateRoot('/tabs/tab1');
}
- angular官网路由与导航章节还介绍跟多路由的高级功能,如有需要请阅读官方文档:
-
CanActivate
路由入口守卫:访问页面前执行业务处理,可以用于访问鉴权,先判断是否有权限访问该页面 -
CanDeactivate
路由出口守卫:离开页面前执行业务处理,如用户填写了表单未保存,点击了返回,可以提示是否保存 -
路由动画:
NavController
在ionic3也有,ionic4继续存在,就是封装了返回/前进动画等功能