Abstract
angular 的路由系统也很容易上手
概览
- 路由懒加载
- 路由事件
- 获取路由参数
- data 的附属信息
- 路由导航
- 路由守卫
基础路由配置
import { DemoComponent } from './components/demo/demo.component';
import { NotFoundComponent } from './components/not-found/not-found.component';
const routes: Routes = [
{
path: 'demo',
component: DemoComponent,
},
{
path: '',
pathMatch: 'full',
redirectTo: '/demo'
},
{
path: '**',
component: NotFoundComponent
}
];
路由懒加载
新建子模块:
ng g m lazy-child --routing
配置子模块路由:
const routes: Routes = [
{
path: 'a',
component: AComponent,
},
{
path: '',
redirectTo: 'a',// 相对于当前路由的地址
pathMatch: 'full',// 最好用full匹配模式,默认是prefix
},
{
path: '**',
redirectTo: 'a'
}
];
在 app 模块进行懒加载:
app-routing.module.ts:
const routes: Routes = [
{
path: 'demo',
component: DemoComponent,
},
{
path: '',
pathMatch: 'full',
redirectTo: '/demo'
},
{
path: 'lazy-child',
loadChildren: ()=> import('./lazy-child/lazy-child.module').then(m=>m.LazyChildModule)
},
{
path: '**',
component: NotFoundComponent
}
];
路由事件
导读
Router接口中给出了 Router 对象的属性说明,其中的 events 属性是一个 Observable 对象,可以用来订阅路由事件。
case-全局路由事件
在根组件 app.component.ts 里:
export class AppComponent {
constructor(private router: Router) {
this.router.events.subscribe((e) => {
console.log('全局路由事件: ', e);
});
}
}
case-路由事件处理
this.router.events.subscribe((e) => {
if (e instanceof NavigationEnd) {
console.log('路由导航完成');
}
});
路由事件参照:RouterEvent
获取路由参数
不使用订阅的方式-ActivatedRouteSnapshot
路由配置 params 占位符:
{
path: 'demo/:id',
component: DemoComponent
}
组件 ts:
demo.component.ts:
constructor(private route: ActivatedRoute) {
console.log(this.route.snapshot)
const url = this.route.snapshot.url[0].path;
const query = this.route.snapshot.queryParams;
const params = this.route.snapshot.params;
console.log('path: ',url)
console.log('query: ',query)
console.log('params: ',params)
}
访问地址:
http://localhost:4200/demo/147?name=test
效果截图:
使用订阅的方式-ActivatedRoute
自行对下面的 Observable 进行订阅即可:
export declare class ActivatedRoute {
/** An observable of the URL segments matched by this route. */
url: Observable<UrlSegment[]>;
/** An observable of the matrix parameters scoped to this route. */
params: Observable<Params>;
/** An observable of the query parameters shared by all the routes. */
queryParams: Observable<Params>;
}
区别:订阅的方式能够实时更新数据。而且,假如你很确定这个组件实例不会被复用,你可以使用 snapshot。(官网话)
路由附属信息-data
route.ts:
{
path: 'demo',
component: DemoComponent,
data: { auth: true },
},
demo.component.ts:
constructor(private route: ActivatedRoute) {
const data = this.route.snapshot.data;
console.log('data: ',data)
}
效果截图:
路由导航
navigateByUrl
使用方式是传入一个绝对路径作为导航的参数
route.ts
constructor(private router: Router) {
this.router.navigateByUrl('/demo/456?test=hahaha')
}
navigate
使用方式是传入 params,和 baseUrl,实现相对地址跳转
在子路由模块中,比如 lazy-child-routing.modules.ts:
const routes: Routes = [
{
path: 'a',
component: AComponent
},
{
path: 'b',
component: BComponent
},
];
有两个子页面。
在 a 组件中:
html:
<p>a works!</p>
<button (click)="handleGo()">点击相对跳转</button>
ts:
constructor(private router: Router, private route: ActivatedRoute) {}
handleGo() {
this.router.navigate(['b'], { relativeTo: this.route.parent});
}
效果:
在 a 页面,点击后,跳转了 b 页面。利用了 parent 的作为 baseUrl。
query 传参
this.router.navigate(['b', { name: 'ggg' }], {
relativeTo: this.route.parent,
});
效果:
跳转至, http://localhost:4200/lazy-child/b;name=ggg
Tips: params 传参方式则需要手动拼接 url
路由守卫
CanActivateFn 路由进入前
CanActivateChildFn 检查子路由进入前
CanDeactivateFn 销毁页面前,确认是否要丢弃当前页面的填写内容
CanDeactivateFn 用于获取路由data
CanMatchFn 懒加载前
case-CanActivateFn
ng g guard auths/auth
auth.guard.ts:
import { inject } from '@angular/core';
import { CanActivateFn, Router } from '@angular/router';
export const authGuard: CanActivateFn = (route, state) => {
const router = inject(Router);
if (route.data['auth']) {
return true;
} else {
router.navigateByUrl('/others');
return false;
}
};
route.ts:
import { authGuard } from './auths/auth.guard';
const routes: Routes = [
{
path: 'demo',
component: DemoComponent,
data: { auth: false },
canActivate: [authGuard]
},
]
效果:
访问/demo 后,跳转至/others。
多个路由守卫
canActivate: [authGuard1, authGuard2]
只有当 authGuard1 守卫返回 true 时,authGuard2 才会继续执行,否则终止这次导航。
异步处理
ng g guard auths/auth2
auth2.guard.ts:
import { Injectable } from '@angular/core';
import {
ActivatedRouteSnapshot,
CanActivate,
RouterStateSnapshot,
UrlTree,
} from '@angular/router';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class Auth2Guard implements CanActivate {
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
):
| Observable<boolean | UrlTree>
| Promise<boolean | UrlTree>
| boolean
| UrlTree {
return new Observable((observer) => {
setTimeout(() => {
console.log('auth2');
observer.next(false);
}, 1000);
});
}
}
route.ts:
{
path: 'demo',
component: DemoComponent,
canActivate: [Auth2Guard]
},
效果:
访问/demo,等待1s后,出现页面。
想要源代码的,戳我博客:
https://gitee.com/gao-hui007/my-blogs/blob/master/docs/angular/Route.md#
转载请说明