前言
上节我们介绍了路由对象,讲解了路由参数的实现源码,知道了通过路由对象获取参数的方法。结合之前的讲解,我们能够总结出路由传参的方法,通过router添加参数,利用route接收参数,但其中过程我们就不得而知了,本节我们就来解析一下路由传参过程。
params参数
前面我们讲解过编程式导航,这里简单回顾一下,通过router的push方法可以进行路由导航,push接收to参数,表示跳转路由的信息,其中就包括params参数:
js
router.push({name:'home',params:{id:'123'}})
注意,通过path跳转式,如果没有name,那么传递params是不会生效。
js
// params参数不会生效
router.push({path:'/home',params:{id:'123'}})
接下来我们就看下params参数是如何保存下来,打开源码找到router的push函数:
push函数就是调用pushWithRedirect ,该函数处理着路由跳转的逻辑,之前简单解析过一点,这里我们就查阅params相关的逻辑。函数最开始通过resolve函数处理to获取到targetLocation,而params就是包含在to参数,很明显resolve函数就是我们要找的。
js
const targetLocation: RouteLocation = (pendingLocation = resolve(to))
resolve考虑了多种情况,首先会对第一个参数rawLocation进行判断,如果是string,会根据string获取到对应的route数据,matchedRoute,此时params就是matchedRoute里的params数据,并且经过decodeParams编码。
push传递的to是对象,不是此逻辑我们继续往下看。接下来会对path进行判断,如果不为null,就会判断params、name是否存在,不符合规则就会给出提示,这就是我们前面提到的params不能只用path的原因。
通过for in循环过滤掉params为null的数据,将过滤过后的params进行编码。
这就是我们从to参数中获取params的过程,除此之外resolve还考虑了currentLocation存在params的情况,此时会将跳转后route自带的params与to中的merge然后重新编码一下。
到此params参数获取结束,后续就是上节介绍过的,通过Inject传递给route让我们在组件中能够获取params。
query参数
query参数最大的特点就是参数值会在url上拼接,query的传递同样可以使用router,并且它没有parms的限制,能够与path使用。
js
router.push({path:'/home',query:{id:'123'}})
有了对params的解析,query解析理解起来就很简单,在resolve函数中,query代码就很简单。
这里用了三目运算,这里用到了stringifyQuery,通过名称就知道,它是将query序列化的函数。
stringifyQuery是RouterOptions的属性,默认就是上面的函数。query参数值是在url上面的,都能看到,为了信息安全有此函数,能够让我们自己将query序列化编码。 originalStringifyQuery就是默认函数,与stringifyQuery相等就说明没有自定义序列化函数,就通过normalizeQuery函数将query进行处理,过滤掉假值情况。
这就是query参数的处理过程,最后还有一点query是怎么拼到url上面呢?resolve中通过stringifyURL获取fullPath,在此过程中会将query拼到url上面。
query参数值也是可以通过route获取,具体的原理上节都提到了,我们不再赘述。
总结
以上就是params与query参数处理的过程,开发中我们传递、获取都很简单,但其过程还是很复杂的,毕竟要考虑很多情况,这也是大佬们的实力。