此次真的是過久過久沒見了,夥伴們。 學習真的沒有鬆懈,只是季度末要衝一衝績效,一會兒把時間都充值了。(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) 大家都不是一我的在戰鬥