关于前端路由复用策略网上的文章很多,大多是讲如何实现tab标签切换历史数据,至于如何复用的原理讲的都比较朦胧,代码样例也很难适用各种各样的路由配置,比如懒加载模式下多级嵌套路由出口网上的大部分代码都会报错。
我希望能通过这篇文章把如何复用路由的原理讲明白,让小伙伴能明明白白的实用路由复用策略,文字中有不详实和错误的地方欢迎小伙伴批评指正

对路由复用策略的理解

路由复用策略的是对路由的父级相同节点的组件实例的复用,我们平时看到的多级嵌套路由切换时上层路由出口的实例并不会从新实例化就是因为angular默认的路由复用策略在起作用,而我们从写路由复用策略能实现很多事情,其中之一就是实现
历史路由状态(数据)的存储,即jquery时代的tab页签和iframe实现操作历史的切换。

我一开始认为路由复用策略就是对历史路由数据的复用策略,这个错误的观念导致我对路由复用策略接口方法理解起来异常困难,不知小伙伴和我犯没犯同样的错误。观念正确了,下面就理解起来比较方便了,写路由复用策略也就比较顺手了。

下面是angular默认路由复用策略,每切换一下路由,下面代码都再默默的执行。


export class DefaultRouteReuseStrategy {
shouldDetach(route) { return false; }
store(route, detachedTree) { }
shouldAttach(route) { return false; }
retrieve(route) { return null; }
shouldReuseRoute(future, curr) {
return future.routeConfig === curr.routeConfig;
}
}

关键概念解释

开始文章前我们先了解几个观念概念

  1. 我们的路由是棵树RouterModule.forRoot(Routes)RouterModule.forChild(Routes)这些配置最后形成一个完整的路由树,路由树有个根是没有routeConfig的,routeConfig是我们写的每个route
  2. 路由节点,一个路径是由几个路由节点组成,有的route配置了component,有的则没有
  3. future下一路由, curr当前路由,切换路由时,我们在下文用future表示下一路由,curr表示当前路由

路由复用策略解析

路由复用策略方法调用顺序

  1. shouldReuseRoute(future, curr)
  2. retrieve(route)
  3. shouldDetach(route)
  4. store(route, detachedTree)
  5. shouldAttach(route)
  6. retrieve,取决一上一步的返回值
  7. store(route, detachedTree),取决第五步

shouldReuseRoute

shouldReuseRoute()决定是否复用路由,根据切换的future curr的节点层级依次调用,返回值为true时表示当前节点层级路由复用,然后继续下一路由节点调用,入参为切换的下一级路由(子级)的future curr路由的节点,返回值为false时表示不在复用路由,并且不再继续调用此方法(future路由不再复用,其子级路由也不会复用,所以不需要再询问下去),root路由节点调用一次,非root路由节点调用两次这个方法,第一次比较父级节点,第二次比较当前节点,

retrieve

retrieve()接上一步奏,当当前层级路由不需要复用的时候,调用一下retrieve方法,其子级路由也会调用一下retrieve方法,如果返回的是null,那么当前路由对应的组件会实例化,这种行为一直持续到末级路由。

shouldDetach

shouldDetach是对上一路由的数据是否实现拆离,其调用开始是当前层级路由不需要复用的时候,即shouldReuseRoute()返回false的时候,如果这时候反回false,将继续到上一路由的下一层级调用shouldDetach,直到返回true或者是最末级路由后才结束对shouldDetach的调用,当返回true时就调用一次store 方法,请看下一步奏

store

store存储路分离出来的上一路由的数据,当 shouldDetach返回true时调用一次,存储应该被分离的那一层的路由的DetachedRouteHandle。注意:无论路由树上多个含有组件component路由节点,能分离出来的只能有一个,被存储的也只能有一个,感觉这种机制对使用场景有很大限制。

shouldAttach

shouldAttach是对当前路由的数据是否实现恢复(附加回来),其调用开始是当前层级路由不需要复用的时候,即shouldReuseRoute()返回false的时候,这和shouldDetach的调用时机很像,但是,并不是所有的路由层级都是有组件实例的,只有包含componentroute才会触发shouldAttach,如果反回false,将继续到当前路由的下一带有component的路由层级调用shouldAttach,直到返回true或者是最末级路由后才结束对shouldAttach
的调用,当返回true时就调用一次retrieve 方法,如果retrieve方法去获取一下当前路由的DetachedRouteHandle,返回一个DetachedRouteHandle,就再调用一次store,再保存一下retrieve返回的DetachedRouteHandle。注意注意:无论路由树上多个含有组件component路由节点,能恢复数据的只能有一个节点,这和shouldDetach是一个套路,对使用场景有很大限制。

总结·这个还是实验性的路由复用策略还是不够强大

路由复用策略这种调用机制对使用场景限制很大 ,比如多级路由出口嵌套就无法实现路由数据缓存。因为多级路由出口嵌套的应用切换路由时,前后路由会包含多个带component的路由节点,而每次对路由的存储和恢复只能存储和恢复某一个节点的component的DetachedRouteHandle,其他路由节点上的component就是被从新实例化。明白这一点后我就放弃了想写一个可以适用任何场景的路由复用策略的想法,如果有小伙伴能解决好这一业务场景,欢迎赐教。

如果这个路由复用策略可以存储一个路由上多个节点的DetachedRouteHandle,和恢复多个节点的DetachedRouteHandle,应该能解决上面是的多级路由出口嵌套场景,但不知道会不会带来别的问题。

一个路由复用策略用例

下面贴一个路由复用策略用例,应该是满足大部分人的业务要求,注意事项:只能是末级路由的缓存,且路由切换的时候路由节点上的component不能超过两个。


import {ActivatedRouteSnapshot, DetachedRouteHandle, Route, RouteReuseStrategy} from "@angular/router"; export class CustomerReuseStrategy implements RouteReuseStrategy {
static handlers: Map<Route, DetachedRouteHandle> = new Map();
shouldDetach(route: ActivatedRouteSnapshot): boolean {
return !route.firstChild;
}
shouldAttach(route: ActivatedRouteSnapshot): boolean {
return !!CustomerReuseStrategy.handlers.has(route.routeConfig);
}
shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot) {
return curr.routeConfig === future.routeConfig;
}
retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
return CustomerReuseStrategy.handlers.get(route.routeConfig);
}
store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
CustomerReuseStrategy.handlers.set(route.routeConfig, handle);
}
}

很精简,但是很好用,小伙伴可以根据自己的业务逻辑进行改造。

如果感觉这篇文章对你有帮助,请点个赞吧

RouteReuseStrategy angular路由复用策略详解,深度刨析路由复用策略的更多相关文章

  1. zz详解深度学习中的Normalization,BN/LN/WN

    详解深度学习中的Normalization,BN/LN/WN 讲得是相当之透彻清晰了 深度神经网络模型训练之难众所周知,其中一个重要的现象就是 Internal Covariate Shift. Ba ...

  2. Kubernetes 部署策略详解-转载学习

    Kubernetes 部署策略详解 参考:https://www.qikqiak.com/post/k8s-deployment-strategies/ 在Kubernetes中有几种不同的方式发布应 ...

  3. 七牛云存储Python SDK使用教程 - 上传策略详解

    文 七牛云存储Python SDK使用教程 - 上传策略详解 七牛云存储 python-sdk 七牛云存储教程 jemygraw 2015年01月04日发布 推荐 1 推荐 收藏 2 收藏,2.7k  ...

  4. TestNG详解-深度好文

    转自: https://blog.csdn.net/lykangjia/article/details/56485295 TestNG详解-深度好文 2017年02月22日 14:51:52 阅读数: ...

  5. guava-retrying 源码解析(等待策略详解)

    一.等待策略相关类: 1.等待策略接口:WaitStrategy接口 该接口只有一个方法,就是返回尝试失败之后,下一次尝试之前的等待时间.long computeSleepTime(Attempt f ...

  6. linux route命令的使用详解 添加永久静态路由 tracert traceroute

    linux route命令的使用详解 添加永久静态路由  tracert  traceroute route -n    Linuxroute  print  Windows traceroute  ...

  7. laravel 配置路由 api和web定义的路由的区别详解

    1.路由经过中间件方面不同 打开kerenl.php就可以看到区别 protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware ...

  8. [转帖]Nginx服务器的六种负载均衡策略详解

    Nginx服务器的六种负载均衡策略详解 咔咔侃技术 2019-09-11 17:40:12 一.关于Nginx的负载均衡 在服务器集群中,Nginx起到一个代理服务器的角色(即反向代理),为了避免单独 ...

  9. angular路由详解五(辅助路由)

    在HTML文件中 //主路由 <router-outlet></router-outlet> //辅助路由 <router-outlet  name="aux& ...

随机推荐

  1. js 数组 splice 函数 多线程

    <script type="text/javascript"> var arr = new Array(6) arr[0] = "00" arr[1 ...

  2. html canvas标签 语法

    html canvas标签 语法 canvas是什么意思? 作用:定义图形,比如图表和其他图像. 说明:<canvas> 标签只是图形容器,通过脚本 (通常是JavaScript)来完成, ...

  3. ZOJ 2301 离散化

    题目链接: 题意是说,有从 1 开始递增依次编号的很多球,开始他们都是黑色的,现在依次给出 n 个操作(ai,bi,ci),每个操作都是把编号 ai 到 bi 区间内的所有球涂成 ci 表示的颜色(黑 ...

  4. 3D Computer Grapihcs Using OpenGL - 19 Vertex Array Object(顶点数组对象)

    大部分OpenGL教程都会在一开始就讲解VAO,但是该教程的作者认为这是很不合理的,因为要理解它的作用需要建立在我们此前学过的知识基础上.因此直到教程已经进行了一大半,作者才引入VAO这个概念.在我看 ...

  5. Spark 2.1.1 源码编译

    Spark 2.1.1 源码编译 标签(空格分隔): Spark Spark 源码编译 环境准备与起因 由于线上Spark On Yarn Spark Streaming程序在消费kafka 写入HD ...

  6. 《Effective Java》读书笔记 - 8.通用编程

    Chapter 8 General Programming Item 45: Minimize the scope of local variables local variables应该在他们要被用 ...

  7. 深入浅出mysql笔记---1、mysql下载安装

    深入浅出mysql笔记---1.mysql下载安装 一.总结 一句话总结: linux下rpm安装即可 1.linux的wget命令作用? 下载文件的工具:比如wget http://cn.wordp ...

  8. legend3---Laravel Homestead的安装和使用

    legend3---Laravel Homestead的安装和使用 一.总结 一句话总结: 配置好homestead之后编码非常方便:在虚拟机或者外部机器里面操作代码两者都会同时改变. 1.Homes ...

  9. eigen 中四元数、欧拉角、旋转矩阵、旋转向量

    一.旋转向量 1.0 初始化旋转向量:旋转角为alpha,旋转轴为(x,y,z) Eigen::AngleAxisd rotation_vector(alpha,Vector3d(x,y,z)) 1. ...

  10. Mybaits 运行原理流程时序图

    1 .初始化sqlsessionFactory 2openSession 3.getMapper返回接口的代理对象 包含了SqlSession对象 4.查询流程