最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Angular路由:懒加载、守卫、动态参数

    正文概述 掘金(DevUI团队)   2021-06-05   444

    DevUI 是一款面向企业中后台产品的开源前端解决方案,它倡导沉浸灵活至简的设计价值观,提倡设计者为真实的需求服务,为多数人的设计,拒绝哗众取宠、取悦眼球的设计。如果你正在开发 ToB工具类产品,DevUI 将是一个很不错的选择!

    Angular路由:懒加载、守卫、动态参数

    引言

    路由是将URL请求映射到具体代码的一种机制,在网站的模块划分、信息架构中扮演了重要的角色,而Angular的路由能力非常强大,我们一起来看看吧。

    路由懒加载

    Angular可以根据路由,动态加载相应的模块代码,这个功能是性能优化的利器。

    为了加快首页的渲染速度,我们可以设计如下的路由,让首页尽量保持简洁、清爽:

    const routes: Routes = [
      {
        path: '',
        children: [
          {
            path: 'list',
            loadChildren: () => import('./components/list/list.module').then(m => m.ListModule),
          },
          {
            path: 'detail',
            loadChildren: () => import('./components/detail/detail.module').then(m => m.DetailModule),
          },
          ...
        ],
      },
    ];
    

    首页只有一些简单的静态元素,而其他页面,比如列表、详情、配置等模块都用loadChildren动态加载。

    效果如下:

    Angular路由:懒加载、守卫、动态参数

    其中的components-list-list-module-ngfactory.js文件,只有当访问/list路由时才会加载。

    路由守卫

    当我们访问或切换路由时,会加载相应的模块和组件,路由守卫可以理解为在路由加载前后的钩子,最常见的是进入路由的守卫和离开路由的守卫:

    • canActivate 进入守卫
    • canDeactivate 离开守卫

    比如我们想在用户进入详情页之前,判断他是否有权限,就可以使用canActivate守卫。

    增加路由守卫

    {
      path: 'detail',
      loadChildren: () => import('./components/detail/detail.module').then(m => m.DetailModule),
    
      // 路由守卫
      canActivate: [AuthGuard],
    },
    

    编写守卫逻辑

    使用CLI命令创建路由守卫模块:

    ng g guard auth
    

    auth.guard.ts

    import { Injectable } from '@angular/core';
    import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from '@angular/router';
    import { Observable } from 'rxjs';
    import { DetailService } from './detail.service';
    
    @Injectable({
      providedIn: 'root'
    })
    export class AuthGuard implements CanActivate {
      constructor(
        private detailService: DetailService,
      ) {}
    
      canActivate(
        route: ActivatedRouteSnapshot,
        state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
        return new Observable(observer => {
          // 鉴权数据从后台接口异步获取
          this.detailService.getDetailAuth().subscribe((hasPermission: boolean) => {
            observer.next(hasPermission);
            observer.complete();
          });
        });
      }
    }
    

    获取权限service

    获取权限的service:

    ng g s detail
    

    detail.service.ts

    import {Injectable} from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    
    @Injectable({ providedIn: 'root' })
    export class DetailService {
      constructor(
        private http: HttpClient,
      ) { }
    
      getDetailAuth(): any {
        return this.http.get('/detail/auth');
      }
    }
    

    效果如下:

    Angular路由:懒加载、守卫、动态参数

    由于我们对/detail路由增加了守卫,不管是从别的路由切换到/detail路由,还是直接访问/detail路由,都无法进入该页面。

    动态路由参数

    在路由中带参数有很多中方法:

    • 在path中带参数
    • 在queryString中带参数
    • 不通过链接带参数

    在path中带参

    {
      path: 'user/:id',
      loadChildren: () => import('./components/user/user.module').then(m => m.UserModule),
    },
    

    在queryString中带参数

    html传参

    <a [routerLink]="['/list']" [queryParams]="{id: '1'}">...</a>
    

    ts传参

    this.router.navigate(['/list'],{ queryParams: { id: '1' });
    

    通过data传递静态参数

    {
      path: 'detail',
      loadChildren: () => import('./components/detail/detail.module').then(m => m.DetailModule),
      
      // 静态参数
      data: {
        title: '详情'
      }
    },
    

    通过resolve传递动态参数

    data只能传递静态参数,那我想通过路由传递从后台接口获取到的动态参数,该怎么办呢?

    答案是通过resolve配置。

    {
      path: 'detail',
      loadChildren: () => import('./components/detail/detail.module').then(m => m.DetailModule),
      
      // 动态路由参数
      resolve: {
        detail: DetailResolver
      },
    },
    

    创建Resolver

    detail.resolver.ts

    import { Injectable } from '@angular/core';
    import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
    import { DetailService } from './detail.service';
    
    @Injectable({ providedIn: 'root' })
    export class DetailResolver implements Resolve<any> {
    
      constructor(private detailService: DetailService) { }
    
      resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): any {
        return this.detailService.getDetail();
      }
    }
    

    在服务中增加获取详情数据的方法

    detail.service.ts

    import {Injectable} from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    
    @Injectable({ providedIn: 'root' })
    export class DetailService {
      constructor(
        private http: HttpClient,
      ) { }
    
      getDetailAuth(): any {
        return this.http.get('/detail/auth');
      }
    
      // 增加的
      getDetail(): any {
        return this.http.get('/detail');
      }
    }
    

    获取动态参数

    创建组件

    ng g c detial
    

    detail.component.ts

    import { Component, OnInit } from '@angular/core';
    import { ActivatedRoute } from '@angular/router';
    
    @Component({
      selector: 'app-detail',
      templateUrl: './detail.component.html',
      styleUrls: ['./detail.component.scss']
    })
    export class DetailComponent implements OnInit {
    
      constructor(
        private route: ActivatedRoute,
      ) { }
    
      ngOnInit(): void {
        // 和获取静态参数的方式是一样的
        const detail = this.route.snapshot.data.detail;
        console.log('detail:', detail);
      }
    
    }
    

    欢迎加DevUI小助手微信:devui-official,一起讨论Angular技术和前端技术。

    欢迎关注我们DevUI组件库,点亮我们的小星星?:

    github.com/devcloudfe/…

    也欢迎使用DevUI新发布的DevUI Admin系统,开箱即用,10分钟搭建一个美观大气的后台管理系统!

    加入我们

    我们是DevUI团队,欢迎来这里和我们一起打造优雅高效的人机设计/研发体系。招聘邮箱:muyang2@huawei.com。

    文/DevUI Kagol

    往期文章推荐

    《今天是儿童节,整个贪吃蛇到编辑器里玩儿吧》

    《如何将龙插入到编辑器中?》

    《Quill富文本编辑器的实践》

    《StepsGuide:一个像跟屁虫一样的组件》

    《号外号外!DevUI Admin V1.0 发布啦!》


    起源地下载网 » Angular路由:懒加载、守卫、动态参数

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元