此次真的是过久过久没见了,伙伴们。 学习真的没有松懈,只是季度末要冲一冲绩效,一会儿把时间都充值了。(ps:我看应该是个人脑子须要充值)前端
系列文章: Vue-Router源码分析之index.jsvue
咱们在使用vue-router的时候,其实就是按照API进行操做,源码其实就是API的另外一种形式,在个人学习中,我发现一味的干货有时效果并很差,由其是深刻思考性比较强的内容。所以本篇文章因此做为一个过渡章节,让咱们一块儿聊一聊承上启下的内容,聊聊API:vue-router
在实际工做中,编程式导航要比<router-link>
标签使用的多的多,复杂逻辑中嵌套路由跳转都是要使用编程式导航。编程
// 字符串
router.push('home')
// 对象
router.push({ path: 'home' })
// 命名的路由
router.push({ name: 'user', params: { userId: 123 }})
router.push({ path: `/user/${userId}` })
// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})
复制代码
在编程式路由中,咱们能够接收一个对象、一个字符串,对象的key有path、name、query、params等等,可是须要相互组合。数组
这么多状况vue-router要对push这么多状况作一个处理,咱们push接收的参数的类型是什么?用flow设定为Location、RawLocationapp
用flow.js设定的类型
declare type Location = {
_normalized?: boolean;
name?: string;
path?: string;
hash?: string;
query?: Dictionary<string>;
params?: Dictionary<string>;
append?: boolean;
replace?: boolean;
}
declare type RawLocation = string | Location
复制代码
翻译过来就是未处理的、生的路径。因此咱们的push操做传递的是一个生冷的路径,通过一次match的处理源码分析
源码内容:
const route = this.router.match(location, this.current)
复制代码
变成vue-router所须要的结构,route类型post
declare type Route = {
path: string;
name: ?string;
hash: string;
query: Dictionary<string>;
params: Dictionary<string>;
fullPath: string;
matched: Array<RouteRecord>;
redirectedFrom?: string;
meta?: any;
}
复制代码
因此从API结合表层源码来看,咱们在进行编程式导航时的过程,先将未处理的路径(ps:vue-router对这种未处理路径无法直接进行跳转等操做)处理成一个规范的route类型,而后进行具体的路由跳转内容。学习
<router-view class="view one"></router-view>
<router-view class="view two" name="a"></router-view>
<router-view class="view three" name="b"></router-view>
const router = new VueRouter({
routes: [
{
path: '/',
components: {
default: Foo,
a: Bar,
b: Baz
}
}
]
})
复制代码
一个组件内能够有多个router-view组件,我接触的几个项目都是维护一个根结点的router-view。大部分都是这种结构
<template>
<div id="app">
<router-view/>
</div>
</template>
复制代码
咱们一个路径下能够展现多个路由视图组件吗?
答案固然是确定的,官方的命名视图的例子(jsfiddle.net/posva/22wgk… 能够看到,咱们在同一个路径下能够放置多个<router-link>
,这里面的name与咱们在构造vue-router时设置的components有对应,咱们通常都是component : xxx
;对应一个组件。如何对应多个的呢?
源码内容:
components: route.components || { default: route.component },
复制代码
其实人家自己但愿你用components,你要只用一我的家就给你包装成一个map,key呢就是默认值的意思。
路由守卫有哪些呢?
1:全局的beforeEach
2:单个路由配置的beforeEnter
3:全局的afterEach
4:组件内的路由守卫:
beforeRouteEnter
beforeRouteUpdate (2.2 新增)
beforeRouteLeave
5:全局的beforeResolve(vue-router2.5新增)
别的守卫还有吗?这么看来是没有了。
全局的beforeEnter、afterEach、beforeResolve为何会做用在每个路由配置中呢?在index一章中,咱们有三个存放守卫的数组你们还有印象吗?
beforeHooks: Array<?NavigationGuard>;
resolveHooks: Array<?NavigationGuard>;
afterHooks: Array<?AfterNavigationHook>;
复制代码
在router实例中存储这些。因此咱们在作路由跳转的时候能够拿到这些守卫,其他的守卫怎么办?只好在跳转的时候具体状况具体执行,
守卫分为三个种类:
1:离开组件以前,2:进入组件(先后都有守卫) 3:更新组件以前
因此一个路由的跳转必定伴随着如下几个步骤
1:跳转咱们称之为transitionTo
2:那么跳转中进行一个confirmTransiton(跳转前的准备)
3:跳转结束时进行一个updateRoute的过程
上文提到的confirmTransition:先收集到全部的守卫,把前置守卫们(前置!!!)链接成一个数组,跳转前挨个执行,前置守卫执行完怎么办?都经过来,那就更新当前路由,更新完当前路由就执行一下后置守卫。 vue-router源码中:
核心的路由跳转方法就是transitionTo: 具体内容是由confirmTransition与updateRoute实现的
其他的一些这这那那的容错,并不影响主流程。
对于push、replace传递的未处理的路径,进行处理成vue-router能够操做的路径。
对于多个router-view,咱们能够选择children,components来实现。
路由守卫为何能够有全局的,每一个路由均可以用,由于在router实例上,咱们每次跳转均可以找到。
路由跳转经历了confirm确认与update更新两步
没有来得及给你们带来祝福,但愿你们十一的时候每次路由跳转都不堵车!
每个前端er(boy and girl) 大家都不是一我的在战斗