本文转载至:https://segmentfault.com/a/1190000010851032

引言

在企业应用中权限、复杂页多路由数据处理、进入与离开路由数据处理这些是非常常见的需求。

当希望用户离开一个正常编辑页时,要中断并提醒用户是否真的要离开时,如果在Angular中应该怎么做呢?

其实Angular路由守卫属性可以帮我们做更多有意义的事,而且非常简单。

什么是路由守卫?

Angular 的 Route 路由参数中除了熟悉的 pathcomponent 外,还包括四种是否允许路由激活与离开的属性。

canActivate

控制是否允许进入路由。

canActivateChild

等同 canActivate,只不过针对是所有子路由。

canDeactivate

控制是否允许离开路由。

canLoad

控制是否允许延迟加载整个模块。

例如:

{ path: 'logics', loadChildren: './logics/logics.module#LogicsModule', canLoad: [ AuthGuard ] }

这四个属性非常好理解,而且作用各自不同。然后当进入与离开能够有效控制权时,对于前面我提到的若干问题,就可以非常好的处理。

如何创建?

四个属性虽然名称不同,但其基本的使用方式非常相近。四种不同守卫方式有者四个不同的接口与之相对应。

属性名 接口名
canActivate CanActivate
canActivateChild CanActivateChild
canDeactivate CanDeactivate<TComponent>
canLoad CanLoad

canDeactivate 需要指明具体的组件类名以外,其他接口只是将首字母大写而已。假定需要一个某个角色才能访问某些路由,就需要一个 CanActivate 守卫类。

@Injectable()
export class CanAdminProvide implements CanActivate {constructor(private userSrv: UserService, private msg: NzMessageService) {}canActivate(route: ActivatedRouteSnapshot,state: RouterStateSnapshot): boolean | Observable<boolean> | Promise<boolean> {return new Observable((observer) => {// 拥有 `admin` 角色if (this.userSrv.hasRole('admin')) {observer.next(true);observer.complete();return;}this.msg.error('授权不足');observer.next(false);observer.complete();});}}

每种接口要都需要相应的实现某个方法,就上而论,继承 CanActivate 并实现一个叫 canActivate 的方法;且返回一个布尔类型的值。

四种类型守卫接口都返回一个布尔类型值,其实从这四种参数的名称 can 开头就不然理解。

最后,把它运用到相应的路由上即可,例如:

{ path: 'admin', component: GuardAdminComponent, canActivate: [ CanAdminProvide ] }

当然,别忘记注册 CanAdminProvide 类。

一些实践

离开时提醒

四种守卫只有一种离开类型 canDeactivate,因此:

@Injectable()
export class CanLeaveProvide implements CanDeactivate<GuardComponent> {constructor (private confirmSrv: NzModalService) {}canDeactivate(component: GuardComponent,currentRoute: ActivatedRouteSnapshot,currentState: RouterStateSnapshot,nextState?: RouterStateSnapshot): boolean | Observable<boolean> | Promise<boolean> {return new Observable((observer) => {this.confirmSrv.confirm({title: '确认要离开吗?',content: '你已经填写了部分表单离开会放弃已经填写的内容。',okText: '离开',cancelText: '取消',onOk: () => {observer.next(true);observer.complete();},onCancel: () => {observer.next(false);observer.complete();}});});}
}

这里返回的是一个 Observable 类型,意味者,在方法体内可以做任何事,只需要在结果中使用:

// 允许
observer.next(true);
// 或拒绝
// observer.next(false);observer.complete();

来处理 Observable 的结果,就完成了整个流程。倘若,用户按浏览器后退或路由至其他页面时,会先收到一个提醒。

上面使用的 ng-zorro-antd 的确认对话框来提醒用户是否需要离开,若选择【离开】则跳转至目标路由,反之保留当前路由状态。

角色受限

这是再正常不过的功能,若用户进入一个未授权的路由时,甚至是某个迟延加载模块下所有路由;若用户无权限时,如何提醒用户。

此时 canActivatecanLoad 就有用了。假定管理员角色才能加载管理模块下所有管理功能以及某个管理页面,基于接口多继承的特性,可以同时继承这两个接口。

@Injectable()
export class CanAuthProvide implements CanActivate, CanLoad {constructor(private userSrv: UserService, private msg: NzMessageService) {}check(): Observable<boolean> {return new Observable((observer) => {if (this.userSrv.isLogin) {observer.next(true);observer.complete();return;}this.msg.error('权限不足');observer.next(false);observer.complete();});}canActivate(route: ActivatedRouteSnapshot,state: RouterStateSnapshot): boolean | Observable<boolean> | Promise<boolean> {return this.check();}canLoad(route: Route): boolean | Observable<boolean> | Promise<boolean> {return this.check();}}

因此,一个类中具有两种不同守卫的能力,更对于代码组织也更优雅。同样,需要运用到相应的路由当中。

{ path: 'auth', component: GuardAuthComponent, canActivate: [ CanAuthProvide ] },
{ path: 'admin', loadChildren: './admin/admin.module#AdminModule', canLoad: [ CanAuthProvide ] }

此后,若一个普通员工账号要想进入(哪怕浏览器地址栏录入)未授权的路由 /auth 会提示 权限不足 的字样。

总结

路由守卫对于权限控制非常便利,当然其粒度当然只能在页面层级。倘若需要对按钮粒度也只能利用指令的方式,而二者的结合可以极大的改善权限控制埋点的代码量。

angular2.0+之路由守卫相关推荐

  1. 路由守卫 AJAX,vue路由导航守卫 和 请求拦截以及基于node的token认证

    #####什么时候需要登录验证与权限控制 1.业务系统通常需要登录才能访问受限资源,在用户未登录情况下访问受限资源需要重定向到登录页面: 2.多个业务系统之间要实现单点登录,即在一个系统或应用已登录的 ...

  2. 创建vue项目(四)路由相关知识、路由守卫、插槽、打包小细节

    一.路由相关点 1. 路由跳转传参以及接参 https://segmentfault.com/a/1190000012393587 方法一: (1) 参数配置: { path : 'xx/:参数变量' ...

  3. reactrouter4路由钩子_react router @4 和 vue路由 详解(八)vue路由守卫

    13.vue路由守卫 a.beforeEach 全局守卫 (每个路由调用前都会触发,根据from和to来判断是哪个路由触发) const router = new VueRouter({ ... }) ...

  4. vue 声明周期函数_vue-router路由守卫-上

    1. 为什么要使用路由守卫?什么是路由守卫? 第一次认识路由守卫:之前我做过的小项目里面,我们直接在浏览器网址的地方进行修改就能跳转页面,这是不安全的,因此就需要路由守卫,实现通过路由拦截,来判断用户 ...

  5. vue2路由手动创建二级路由路由传参路由守卫打包上线

    路由手动配置: #在@vue/cli创建的项目中,路由用法如下. 1.安装路由npm install vue-router@32:定义路由所需的组件(.vue文件)要实现页面about 和home两个 ...

  6. Vue路由守卫(拦截)

    要解决的问题:最近做项目时,发现不登录账号和密码,在浏览器的地址栏直接输入路径也能跳转页面,就聊一下路由守卫吧,也叫路由拦截,话不多少 直接看操作 解决方案:在登录成功后,设置一个sessionSto ...

  7. vue2进阶篇:vue-router之“使用独享路由守卫”

    文章目录 10.13路由守卫 案例:将案例改为"使用独享路由守卫" 完整代码 本人其他相关文章链接 10.13路由守卫 注意点1: 前置路由守卫或者后置路由守卫中,to指代切换到哪 ...

  8. 使用路由守卫来写登录效果

    美食杰项目的登录效果 1.使用element-ui写样式 <template><div class="login-section"><!-- :rul ...

  9. vue-cli 初始化创建 vue2.9.6 项目路由守卫、封装axios、vuex

    阅读目录 Vue如何封装Axios请求 1 安装axios 2 封装代码 axios 应用方式 Vue 中的路由守卫 使用演示 1 全局守卫 2 组件级守卫 3 单个路由独享的守卫 4 官网整个路由守 ...

最新文章

  1. Linux_RHEL7_YUM
  2. 怎样用MATLAB将矩阵输出为图像并存到硬盘上-图像保存到硬盘
  3. Android Studio系列教程一:下载与安装
  4. 【Paper】论文中定义、定理、引理、证明分别的含义
  5. html5家谱资源网,免费家谱系统(ASP,Access,CSS,html5)
  6. K8S Calico
  7. 那些基础不好的程序员,后来怎么样了?
  8. 纯css 无视宽高设置垂直水平居中
  9. 文件的属性 计算机知识,计算机基础知识文件的属性(二)
  10. 删除单链表中的重复节点
  11. Android UI学习之Dialog
  12. 如何将图片转化为base64编码格式显示
  13. 老饼教你深入浅出理解-《牛顿法求极值》
  14. Cholesky Decomposition(Cholesky分解)
  15. java 无理数_《数学分析原理》笔记之——无理数的引入
  16. python语句中生成小数的语句_下列 Python 语句的输出结果是 。 print( 数量 {0}, 单价 {1} .format(100,285.6)) print(str.format(...
  17. 2022年全球市场介质浆料总体规模、主要生产商、主要地区、产品和应用细分研究报告
  18. OSChina 周五乱弹 —— 看来我只适合当一个千斤顶
  19. Google地图的Street View和Mapplets
  20. 2.光栅图形显示技术

热门文章

  1. 乡村振兴,表达不可能,和表达没有,无脑表达,伤害表达,高精神平行表达
  2. 死锁的概念以及发生死锁的缘由
  3. fontweight 失效的原因
  4. 格力董事风波意义何在?
  5. Python读取word文档(结尾是docx)中的表格
  6. 几个很“高雅”的测试
  7. Elasticsearch配置ik中文分词器自定义词库
  8. 从产品销量考虑渠道布局——洗衣机行业数据分析
  9. 南京邮电大学电工电子基础B实验四(戴维南与诺顿定理)
  10. 社交网站击溃游戏专业队 占领近9成网页游戏市场