學習vue-router的記錄

前言

vue-router是什么:是vue.js官方的路由管理器和vue.js的核心深度的集成,讓開發者更加簡單的構建單頁面應用。

vue-router的功能是什么:嵌套的路由/視圖表

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 模塊化的、基于組件的路由配置

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 路由參數、查詢、通配符

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 基于vue.js過渡系統的視圖過渡效果

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 細粒度的導航控制(控制的很精細的意思,對很多細節也進行控制)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 帶有自動激活的 css class?鏈接

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?HTML5歷史模式或hash模式,在IE中自動降級

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?自定義滾動條行為

基礎

vue-router構建單頁面應用,只需要將組件映射到路由,熱后告訴vue-router在哪里渲染它們

簡單的例子:

最基礎的例子

使用vue-router有幾個方法

直接利用import引入router.js文件,在文件中寫組件的路由

組件中寫的路由

利用編程式的導航

編程式的導航寫法

動態路由的匹配

有時候我們需要把某種模式匹配到的所有路由,全都映射到同個組件時,我們就會用到動態路由的匹配,路徑參數使用:標記當匹配到一個路由時,參數值會被設置到?this.$route.params,可以在每個組件內使用。

動態路由的html
動態路由的js

響應路由參數的變化

當使用路由參數時,原來的組件實例會被復用。因為兩個路由都渲染同個組件,比起銷毀再創建,復用則顯得更加高效,生命鉤子不被再次調用。復用組件時,想對路由參數的變化作出響應的話,可以用以下兩種方式

響應路由參數的變化的兩種方法

因為mounted ,created不會再調用?,?可以這兩種方式監聽參數變化,做相應的業務邏輯處理

匹配優先級

匹配的優先級就按照路由的定義順序:誰先定義的,誰的優先級就最高。

嵌套路由

要在嵌套的出口中渲染組件,需要在VueRouter的參數中使用children配置

嵌套路由的寫法

注意:以/開頭的嵌套路徑會當作根路徑,充分使用嵌套組件而無須設置嵌套路徑,children?配置就是像?routes?配置一樣的路由配置數組,所以呢,你可以嵌套多層路由。

編程式導航

this.$router.push(location,onComplete?,onAbort?)

除了使用??創建 a 標簽來定義導航鏈接,我們還可以借助 router 的實例方法,通過編程式導航來實現:?this.$router.push({path:' '}} 。

這方法會向history棧添加一個新的記錄,所以,當用戶點擊瀏覽器后退按鈕時,則回到之前的地址

各種$router.push{{path:' '}}寫法

使用了path,params會被忽略,同樣的規則也適用于?router-link?組件的?to?屬性。

this.$router.replace (location,onComplete?,onAbort?)

和router.push很像唯一的不同是,它不會向history添加新紀錄,而是替換當前的history記錄

聲明式:<router-link :to="..."? replace>

編程式:router.replace(...)

router go(n)

n為整數,意思是在history記錄中向前或后退多少步,類似window.history.go(n)

router.go()用法

命名路由

有時,在通過名稱來進行頁面路由跳轉會方便很多,可以在創建實例的時候給路由設置名稱

設置名稱name寫法

使用方法:

html使用name寫法
js使用name寫法

命名視圖

有時候想要同時(同級)展示多個視圖,而不是嵌套展示,這時候就可以使用命名視圖的方法,命名視圖首先需要在路由配置上命名組件是名字,使用<router-view?name=" "></router-view>來實現。

命名組件的name
使用命名視圖的方法

嵌套命名路由

命名嵌套路由的name
使用命名嵌套路由

重定向和別名

重定向(redirect)

使用redirect重定向目標
目標重定向為命名路由
目標重定向為方法

別名(alias)

/a?的別名是?/b,則當用戶訪問?/b?時,URL 會保持為?/b,但是路由匹配為?/a,就像用戶訪問?/a?一樣。
“別名”的功能讓你可以自由地將 UI 結構映射到任意的 URL,不會受限于配置的嵌套路由結構。

?別名的寫法

路由組件傳參

使用$router會使其于路由高度耦合,從而使組件只能在特定的 URL 上使用

可以使用props對其組件和路由進行解耦

使用props解耦的寫法

布爾模式

如果?props?被設置為?true,route.params?將會被設置為組件屬性。

對象模式

props?是一個對象,它會被按原樣設置為組件屬性,當?props?是靜態的時候有用。

函數模式

你可以創建一個函數返回?props。這樣你便可以將參數轉換成另一種類型,將靜態值與基于路由的值結合等。盡可能保持?props?函數為無狀態,因為它只會在路由發生變化時起作用。

HTML5 History 模式

vue-router?默認使用 hash 模式,使用 URL 的 hash 來模擬一個完整的 URL,當 URL 改變時,頁面不會重新加載。使用history模式時url會好看些(如:http://?dayou.com/user/id),完成 URL 跳轉而無須重新加載頁面。這種模式需要后臺配置支持,因為我們的應用是個單頁客戶端應用,如果后臺沒有正確的配置,當用戶在瀏覽器直接訪問?http://oursite.com/user/id?就會返回 404。服務端需要增加一個覆蓋所有情況的候選資源,如果 URL 匹配不到任何靜態資源,則應該返回同一個?index.html?頁面。

進階

導航守衛

vue-router?提供的導航守衛主要用來通過跳轉或取消的方式守衛導航,參數或查詢的改變并不會觸發進入/離開的導航守衛。可以觀察$router對象來應對這些變化用?beforeRouteUpdate?的組件內守衛,進入路由前先通過守衛,來判斷是否可以通過,進而到達頁面。

全局守衛

使用?router.beforeEach?注冊一個全局前置守衛,在定義router的地方定義

全局守衛的寫法

一個導航觸發時,全局前置守衛按照創建順序調用。守衛是異步解析執行,此時導航在所有守衛 resolve(解決) 完之前一直處于等待的狀態。

to: Route: 即將要進入的目標?路由對象

from: Route: 當前導航正要離開的路由

next: Function: 一定要調用該方法來?resolve?這個鉤子。執行效果依賴?next?方法的調用參數。

next(): 進行管道中的下一個鉤子。如果全部鉤子執行完了,則導航的狀態就是?confirmed?(確認的)。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

next(false): 中斷當前的導航。如果瀏覽器的 URL 改變了 (可能是用戶手動或者瀏覽器后退按鈕),那么 URL 地址會重置到?from?路由對應的地址。

next('/')?或者?next({ path: '/' }): 跳轉到一個不同的地址。當前的導航被中斷,然后進行一個新的導航。你可以向?next?傳遞任意位置對象,且允許設置諸如?replace: true、name: 'home'之類的選項以及任何用在?router-link?的?to?prop?或?router.push?中的選項。

next(error): (2.4.0+) 如果傳入?next?的參數是一個?Error?實例,則導航會被終止且該錯誤會被傳遞給?router.onError()?注冊過的回調。?

確保要調用?next?方法,否則鉤子就不會被 resolved。

全局解析守衛( router.beforeResolve )

和全局守衛區別是在導航被確認之前,同時在所有組件內守衛和異步路由組件被解析之后,解析守衛就被調用。

全局后置鉤子

全局后置鉤子不接受next函數也不會改變導航本身

全局后置鉤子寫法

路由獨享守衛

在路由配置上直接定義?beforeEnter?守衛

路由獨享守衛寫法

組件內的守衛

路由組件內直接定義路由導航守衛:beforeRouteEnter,beforeRouteUpdate,beforeRouteLeave

組件內守衛寫法和要注意的部分

beforeRouteEnter( )不能獲取組件實例this,不過可以通過傳一個回調給?next來訪問組件實例。在導航被確認的時候執行回調,并且把組件實例作為回調方法的參數。

組件實例作為回調方法的寫法

beforeRouteEnter?是支持next傳遞回調的唯一守衛。

對于?beforeRouteUpdate?和?beforeRouteLeave?來說,this?已經可用了,所以不支持傳遞回調

離開守衛通常用來禁止用戶在還未保存修改前突然離開。該導航可以通過?next(false)?來取消

離開守衛next(false)寫法

完整的導航解析流程

1、導航被觸發。

2、在失活的組件里調用離開守衛。

3、調用全局的?beforeEach?守衛。

4、在重用的組件里調用?beforeRouteUpdate?守衛 (2.2+)。

5、在路由配置里調用?beforeEnter。

6、解析異步路由組件。

7、在被激活的組件里調用?beforeRouteEnter。

8、調用全局的?beforeResolve?守衛 (2.5+)。

9、導航被確認。

10、調用全局的?afterEach?鉤子。

11、觸發 DOM 更新。

12、用創建好的實例調用?beforeRouteEnter?守衛中傳給?next?的回調函數。

路由元信息

定義路由的時可配置?meta?字段:

路由配置meta字段

我們稱呼?routes?配置中的每個路由對象為?路由記錄。路由記錄可以是嵌套的,因此,當一個路由匹配成功后,可能匹配多個路由記錄

那么如何訪問這個?meta?字段呢

訪問 meta?字段

要確保最后使用了next( )

過渡效果

?是基本的動態組件,我們可以用組件給它添加過渡效果

添加過渡效果

單個路由的過渡效果

如果只想讓部分路由有過渡效果或者想路由的效果不同可在各路由組件內使用<transition>并且設置不同的name值

設置不同的name值

基于路由的動態過渡效果

基于當前路由與目標路由的變化關系,動態設置過渡效果

動態的綁定name
父組件判定路由動態過渡效

數據獲取

我們經常需要在頁面加載的時候獲取對應的數據,我們可以通過以下的兩種方式進行:

導航完成之后獲取:先完成導航,然后在接下來的組件生命周期鉤子中獲取數據。在數據獲取期間顯示“加載中”之類的指示。

導航完成之前獲取:導航完成前,在路由進入的守衛中獲取數據,在數據獲取成功后執行導航。

導航完成之后獲取

當你使用這種方式時,我們會馬上導航和渲染組件,然后在組件的?created?鉤子中獲取數據。這讓我們有機會在數據獲取期間展示一個 loading 狀態,還可以在不同視圖間展示不同的 loading 狀態。

導航完成之前獲取

這種方式我們在導航轉入新的路由前獲取數據。我們可以在接下來的組件的?beforeRouteEnter?守衛中獲取數據,當數據獲取成功后只調用?next?方法。

滾動行為

當切換到新路由時,想要頁面滾到頂部,或是保持原先的滾動位置,就像重新加載頁面那樣。

當創建一個 Router 實例,你可以提供一個?scrollBehavior?方法:

滾動到錨點處或者頭部?

異步滾動

如果在不知道要滾動到那個具體位置,則可以使用異步滾動,獲取后臺要滾動到的具體位置,返回一個 Promise 來得出預期的位置描述:

異步滾動使用實例

將其掛載到從頁面級別的過渡組件的事件上,令其滾動行為和頁面過渡一起良好運行是可能的

路由懶加載

當打包構建應用時,Javascript 包會變得非常大,影響頁面加載。

所以我們把不同路由對應的組件分割成不同的代碼塊,然后當路由被訪問的時候才加載對應組件,這樣就更加高效了。

結合 Vue 的異步組件和 Webpack 的代碼分割功能,輕松實現路由組件的懶加載。

首先,可以將異步組件定義為返回一個 Promise 的工廠函數 (該函數返回的 Promise 應該 resolve 組件本身):

const Foo = () => Promise.resolve({ /* 組件定義對象 */ })

第二,在 Webpack 2 中,我們可以使用動態 import語法來定義代碼分塊點 (split point):

import('./Foo.vue') // 返回 Promise

定義一個能夠被 Webpack 自動代碼分割的異步組件

const Foo = () => import('./Foo.vue')

把組件按組分塊

有時候我們想把某個路由下的所有組件都打包在同個異步塊 (chunk) 中

const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')

const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue')

const Baz = () => import(/* webpackChunkName: "group-foo" */ './Baz.vue')

Webpack 會將任何一個異步模塊與相同的塊名稱組合到相同的異步塊中。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,578評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,701評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,691評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,974評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,694評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,026評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,015評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,193評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,719評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,442評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,668評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,151評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,846評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,255評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,592評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,394評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容

  • 學習目的 學習Vue的必備技能,必須 熟練使用 Vue-router,能夠在實際項目中運用。 Vue-rout...
    _1633_閱讀 92,407評論 3 58
  • vue-router學習筆記 安裝 并且如果在一個模塊化工程中使用它,必須要通過Vue.use()明確地安裝路由功...
    EL_PSY_CONGROO閱讀 593評論 0 0
  • Vue-Router簡介 Vue-Router是Vue.js官方維護的路由插件,同時也是官方推薦的路由插件。它與V...
    SunnySky_閱讀 852評論 0 1
  • 導航守衛 導航守衛主要用來通過跳轉或取消的方式守衛導航。 參數或查詢的改變并不會觸發進入/離開的導航守衛。 1、全...
    SailingBytes閱讀 1,186評論 1 3
  • 用Vue.js + vue-router創建單頁應用,是非常簡單的,基本是這樣的: 組件 → 路由 → 渲染地方 ...
    阿go閱讀 1,413評論 0 0