Angular 路由系统

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#
转载请说明

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值