十、vue-router学习笔记——认识路由、vue-router基本使用、vue-router嵌套路由、vue-router参数传递、vue-router导航守卫、keep-alive
一、認(rèn)識路由
1.1 什么是路由?
說起路由你想起了什么?
路由是一個網(wǎng)絡(luò)工程里面的術(shù)語。
路由(routing)就是通過互聯(lián)的網(wǎng)絡(luò)把信息從源地址傳輸?shù)侥康牡刂返幕顒? — 維基百科
額, 啥玩意? 沒聽懂
在生活中, 我們有沒有聽說過路由的概念呢? 當(dāng)然了, 路由器嘛.
路由器是做什么的? 你有想過嗎?
路由器提供了兩種機(jī)制: 路由和轉(zhuǎn)送.
- 路由是決定數(shù)據(jù)包從來源到目的地的路徑.
- 轉(zhuǎn)送將輸入端的數(shù)據(jù)轉(zhuǎn)移到合適的輸出端.
路由中有一個非常重要的概念叫路由表.
路由表本質(zhì)上就是一個映射表, 決定了數(shù)據(jù)包的指向.
1.2 后端路由階段
早期的網(wǎng)站開發(fā)整個HTML頁面是由服務(wù)器來渲染的.
- 服務(wù)器直接生產(chǎn)渲染好對應(yīng)的HTML頁面, 返回給客戶端進(jìn)行展示.
但是, 一個網(wǎng)站, 這么多頁面服務(wù)器如何處理呢?
- 一個頁面有自己對應(yīng)的網(wǎng)址, 也就是URL.
- URL會發(fā)送到服務(wù)器, 服務(wù)器會通過正則對該URL進(jìn)行匹配, 并且最后交給一個Controller進(jìn)行處理.
- Controller進(jìn)行各種處理, 最終生成HTML或者數(shù)據(jù), 返回給前端.
- 這就完成了一個IO操作.
上面的這種操作, 就是后端路由.
- 當(dāng)我們頁面中需要請求不同的路徑內(nèi)容時, 交給服務(wù)器來進(jìn)行處理, 服務(wù)器渲染好整個頁面, 并且將頁面返回給客戶端.
- 這種情況下渲染好的頁面, 不需要單獨加載任何的js和css, 可以直接交給瀏覽器展示, 這樣也有利于SEO的優(yōu)化.
后端路由的缺點:
- 一種情況是整個頁面的模塊由后端人員來編寫和維護(hù)的.
- 另一種情況是前端開發(fā)人員如果要開發(fā)頁面, 需要通過PHP和Java等語言來編寫頁面代碼.
- 而且通常情況下HTML代碼和數(shù)據(jù)以及對應(yīng)的邏輯會混在一起, 編寫和維護(hù)都是非常糟糕的事情.
1.3 前端路由階段
前后端分離階段:
- 隨著Ajax的出現(xiàn), 有了前后端分離的開發(fā)模式.
- 后端只提供API來返回數(shù)據(jù), 前端通過Ajax獲取數(shù)據(jù), 并且可以通過JavaScript將數(shù)據(jù)渲染到頁面中.
- 這樣做最大的優(yōu)點就是前后端責(zé)任的清晰, 后端專注于數(shù)據(jù)上, 前端專注于交互和可視化上.
- 并且當(dāng)移動端(iOS/Android)出現(xiàn)后, 后端不需要進(jìn)行任何處理, 依然使用之前的一套API即可.
- 目前很多的網(wǎng)站依然采用這種模式開發(fā).
單頁面富應(yīng)用階段:
- 其實SPA最主要的特點就是在前后端分離的基礎(chǔ)上加了一層前端路由.
- 也就是前端來維護(hù)一套路由規(guī)則.
前端路由的核心是什么呢?
- 改變URL,但是頁面不進(jìn)行整體的刷新。
- 如何實現(xiàn)呢?
URL的hash也就是錨點(#), 本質(zhì)上是改變window.location的href屬性.
我們可以通過直接賦值location.hash來改變href, 但是頁面不發(fā)生刷新
- history接口是HTML5新增的, 它有五種模式改變URL而不刷新頁面.
- history.pushState()
HTML5的history模式:replaceState
HTML5的history模式:go
補(bǔ)充說明:
上面只演示了三個方法
- 因為 history.back() 等價于 history.go(-1)
- history.forward() 則等價于 history.go(1)
這三個接口等同于瀏覽器界面的前進(jìn)后退。
二、vue-router基本使用
2.1 認(rèn)識vue-router
目前前端流行的三大框架, 都有自己的路由實現(xiàn):
- Angular的ngRouter
- React的ReactRouter
- Vue的vue-router
當(dāng)然, 我們的重點是vue-router
- vue-router是Vue.js官方的路由插件,它和vue.js是深度集成的,適合用于構(gòu)建單頁面應(yīng)用。
- 我們可以訪問其官方網(wǎng)站對其進(jìn)行學(xué)習(xí): https://router.vuejs.org/zh/
vue-router是基于路由和組件的
- 路由用于設(shè)定訪問路徑, 將路徑和組件映射起來.
- 在vue-router的單頁面應(yīng)用中, 頁面的路徑的改變就是組件的切換.
2.2 安裝和使用vue-router
因為我們已經(jīng)學(xué)習(xí)了webpack, 后續(xù)開發(fā)中我們主要是通過工程化的方式進(jìn)行開發(fā)的.
所以在后續(xù), 我們直接使用npm來安裝路由即可.
創(chuàng)建router實例:
2.3 使用vue-router的步驟:
第一步: 創(chuàng)建路由組件
第二步: 配置路由映射: 組件和路徑映射關(guān)系
第三步: 使用路由: 通過<router-link>和<router-view>
2.4 完整流程
注意:
- <router-link>: 該標(biāo)簽是一個vue-router中已經(jīng)內(nèi)置的組件, 它會被渲染成一個<a>標(biāo)簽.
- <router-view>: 該標(biāo)簽會根據(jù)當(dāng)前的路徑, 動態(tài)渲染出不同的組件.
網(wǎng)頁的其他內(nèi)容, 比如頂部的標(biāo)題/導(dǎo)航, 或者底部的一些版權(quán)信息等會和<router-view>處于同一個等級. - 在路由切換時, 切換的是<router-view>掛載的組件, 其他內(nèi)容不會發(fā)生改變.
2.5 路由的默認(rèn)路徑
我們這里還有一個不太好的實現(xiàn):
- 默認(rèn)情況下, 進(jìn)入網(wǎng)站的首頁, 我們希望<router-view>渲染首頁的內(nèi)容.
- 但是我們的實現(xiàn)中, 默認(rèn)沒有顯示首頁組件, 必須讓用戶點擊才可以.
如何可以讓路徑默認(rèn)跳到到首頁, 并且<router-view>渲染首頁組件呢?
- 非常簡單, 我們只需要配置多配置一個映射就可以了.
配置解析: - 我們在routes中又配置了一個映射.
- path配置的是根路徑: /
- redirect是重定向, 也就是我們將根路徑重定向到/home的路徑下, 這樣就可以得到我們想要的結(jié)果了.
2.6 不使用hash方式,采用HTML5的History模式
我們前面說過改變路徑的方式有兩種:
- URL的hash
- HTML5的history
- 默認(rèn)情況下, 路徑的改變使用的URL的hash.
如果希望使用HTML5的history模式, 非常簡單, 進(jìn)行如下配置即可:
2.7 router-link補(bǔ)充
-
在前面的<router-link>中, 我們只是使用了一個屬性: to, 用于指定跳轉(zhuǎn)的路徑.
-
<router-link>還有一些其他屬性:
tag: tag可以指定<router-link>之后渲染成什么組件, 比如上面的代碼會被渲染成一個<li>元素, 而不是<a>
replace:replace不會留下history記錄, 所以指定replace的情況下, 后退鍵返回不能返回到上一個頁面中
active-class: 當(dāng)<router-link>對應(yīng)的路由匹配成功時, 會自動給當(dāng)前元素設(shè)置一個router-link-active的class, 設(shè)置active-class可以修改默認(rèn)的名稱.
該class具體的名稱也可以通過router實例的屬性進(jìn)行修改 ,即也可以在路由中配置linkActiveClass選項來修改激活狀態(tài)的類名:
- 在進(jìn)行高亮顯示的導(dǎo)航菜單或者底部tabbar時, 會使用到該類.
- 但是通常不會修改類的屬性, 會直接使用默認(rèn)的router-link-active即可.
補(bǔ)充:exact-active-class - 類似于active-class, 只是在精準(zhǔn)匹配下才會出現(xiàn)的class.
- 后面看到嵌套路由時, 我們再看下這個屬性.
2.8 路由代碼跳轉(zhuǎn)
有時候, 頁面的跳轉(zhuǎn)可能需要執(zhí)行對應(yīng)的JavaScript代碼, 這個時候, 就可以使用第二種跳轉(zhuǎn)方式了
比如, 我們將代碼修改如下:
2.9 動態(tài)路由
在某些情況下,一個頁面的path路徑可能是不確定的,比如我們進(jìn)入用戶界面時,希望是如下的路徑:
- /user/aaaa或/user/bbbb
- 除了有前面的/user之外,后面還跟上了用戶的ID
- 這種path和Component的匹配關(guān)系,我們稱之為動態(tài)路由(也是路由傳遞數(shù)據(jù)的一種方式)。
2.10 認(rèn)識路由的懶加載
官方給出了解釋:
- 當(dāng)打包構(gòu)建應(yīng)用時,Javascript 包會變得非常大,影響頁面加載。
- 如果我們能把不同路由對應(yīng)的組件分割成不同的代碼塊,然后當(dāng)路由被訪問的時候才加載對應(yīng)組件,這樣就更加高效了
官方在說什么呢?
- 首先, 我們知道路由中通常會定義很多不同的頁面.
- 這個頁面最后被打包在哪里呢? 一般情況下, 是放在一個js文件中.
- 但是, 頁面這么多放在一個js文件中, 必然會造成這個頁面非常的大.
- 如果我們一次性從服務(wù)器請求下來這個頁面, 可能需要花費一定的時間, 甚至用戶的電腦上還出現(xiàn)了短暫空白的情況.
如何避免這種情況呢? 使用路由懶加載就可以了.
路由懶加載做了什么?
- 路由懶加載的主要作用就是將路由對應(yīng)的組件打包成一個個的js代碼塊.
- 只有在這個路由被訪問到的時候, 才加載對應(yīng)的組件
路由懶加載的效果
懶加載的方式:
三、vue-router嵌套路由
3.1 認(rèn)識嵌套路由
嵌套路由是一個很常見的功能
- 比如在home頁面中, 我們希望通過/home/news和/home/message訪問一些內(nèi)容.
- 一個路徑映射一個組件, 訪問這兩個路徑也會分別渲染兩個組件.
路徑和組件的關(guān)系如下:
實現(xiàn)嵌套路由有兩個步驟:
創(chuàng)建對應(yīng)的子組件:
在路由映射中配置對應(yīng)的子路由:
在組件內(nèi)部使用標(biāo)簽:
四、vue-router參數(shù)傳遞
4.1 傳遞參數(shù)主要有兩種類型: params和query
1. params的類型:
-
配置路由格式: /router/:id
-
傳遞的方式: 在path后面跟上對應(yīng)的值
-
傳遞后形成的路徑: /router/123, /router/abc
2. query的類型:
-
配置路由格式: /router, 也就是普通配置
-
傳遞的方式: 對象中使用query的key作為傳遞方式
-
傳遞后形成的路徑: /router?id=123, /router?id=abc
4.2 傳遞過來的參數(shù)的使用方式
如何使用它們呢? 也有兩種方式: <router-link>的方式和JavaScript代碼方式
傳遞參數(shù)方式一: <router-link>
傳遞參數(shù)方式二: JavaScript代碼
4.3 在組件中獲取參數(shù)的方法:
- 獲取參數(shù)通過$route對象獲取的.
- 在使用了 vue-router 的應(yīng)用中,路由對象會被注入每個組件中,賦值為this.$route ,并且當(dāng)路由切換時,路由對象會被更新。
通過$route獲取傳遞的信息如下:
4.4 $route和$router是有區(qū)別的
五、vue-router導(dǎo)航守衛(wèi)
5.1 為什么使用導(dǎo)航守衛(wèi)?
我們來考慮一個需求: 在一個SPA應(yīng)用中, 如何改變網(wǎng)頁的標(biāo)題呢?
- 網(wǎng)頁標(biāo)題是通過<title>來顯示的, 但是SPA只有一個固定的HTML, 切換不同的頁面時, 標(biāo)題并不會改變.
- 但是我們可以通過JavaScript來修改<title>的內(nèi)容.window.document.title = '新的標(biāo)題'.
那么在Vue項目中, 在哪里修改? 什么時候修改比較合適呢?
- 我們比較容易想到的修改標(biāo)題的位置是每一個路由對應(yīng)的組件.vue文件中.
- 通過mounted聲明周期函數(shù), 執(zhí)行對應(yīng)的代碼進(jìn)行修改即可.
- 但是當(dāng)頁面比較多時, 這種方式不容易維護(hù)(因為需要在多個頁面執(zhí)行類似的代碼).
什么是導(dǎo)航守衛(wèi)?
- vue-router提供的導(dǎo)航守衛(wèi)主要用來監(jiān)聽路由的進(jìn)入和離開的.
- vue-router提供了beforeEach和afterEach的鉤子函數(shù), 它們會在路由即將改變前和改變后觸發(fā).
5.2 導(dǎo)航守衛(wèi)使用
我們可以利用beforeEach來完成標(biāo)題的修改.
- 首先, 我們可以在鉤子當(dāng)中定義一些標(biāo)題, 可以利用meta來定義
- 其次, 利用導(dǎo)航守衛(wèi),修改我們的標(biāo)題.
導(dǎo)航鉤子的三個參數(shù)解析:
5.3 導(dǎo)航守衛(wèi)補(bǔ)充
補(bǔ)充一:如果是后置鉤子, 也就是afterEach, 不需要主動調(diào)用next()函數(shù).
補(bǔ)充二: 上面我們使用的導(dǎo)航守衛(wèi), 被稱之為全局守衛(wèi).
-
路由獨享的守衛(wèi).
-
組件內(nèi)的守衛(wèi).
更多內(nèi)容, 可以查看官網(wǎng)進(jìn)行學(xué)習(xí)
六、keep-alive
keep-alive 是 Vue 內(nèi)置的一個組件,可以使被包含的組件保留狀態(tài),或避免重新渲染。
- 它們有兩個非常重要的屬性:
- include - 字符串或正則表達(dá),只有匹配的組件會被緩存
- exclude - 字符串或正則表達(dá)式,任何匹配的組件都不會被緩存
由于exclude 排除了Profile,User組件,所以Profile,User組件都不會被緩存,就會被反復(fù)的創(chuàng)建和銷毀:
router-view 也是一個組件,如果直接被包在 keep-alive 里面,所有路徑匹配到的視圖組件都會被緩存:
通過created聲明周期函數(shù)來驗證
不使用keep-alive的情況:
首頁組件被反復(fù)的創(chuàng)建和銷毀
使用keep-alive的情況:
首頁不會被反復(fù)創(chuàng)建和銷毀
總結(jié)
以上是生活随笔為你收集整理的十、vue-router学习笔记——认识路由、vue-router基本使用、vue-router嵌套路由、vue-router参数传递、vue-router导航守卫、keep-alive的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JS面向对象——Object对象的方法补
- 下一篇: 指令系统——数据寻址(3)——堆栈寻址(