vue-router總結2
在上一篇總結了vue-router中的路由切換、重定向和路由傳參等知識,因為篇幅的原因,便將剩下的路由模組化、路由巢狀、history模式、路由守衛等放在這裡來寫了。因為是繼續前面的寫。所以程式碼也還是用的前面的,有需要的可以自己去上一篇的最後下載。
新視窗開啟
在vue中,路由跳轉有兩種模式,而這兩種模式下的新視窗開啟方式也是不一樣的。
router-link路由導航
因為router-link在DOM中的最終渲染結果就是<a>標籤,所以可以採用<a>標籤的方法,為元素新增target="_blank"屬性就可以了。
這樣,當點選導航按鈕跳轉到one.vue頁面的時候,會是在新視窗開啟這個頁面。
程式設計式導航
程式設計式導航要實現新視窗開啟頁面,需要藉助$router.resolve,在前面,我們在one.vue頁面中添加了一個按鈕,併為這個按鈕添加了點選事件,跳轉到two.vue頁面。
如果要想實現在新視窗開啟目標頁面,只需要修改事件方法就可以了。
路由模組化
到目前為止,專案中所有與路由相關的內容都放置在了src資料夾下面的router資料夾下的router.js檔案中。
但是在實際的專案中,路由肯定比現在的複雜,而且可能還需要新增路由守衛等等,如果將所有的內容全部放在一個檔案裡面,是不便於維護的,所以需要使用模組化路由。
首先需要在router資料夾下新建index.js檔案,然後對之前router.js裡面的內容進行分割,並在index.js中引入router.js
然後,因為在之前,所有的內容都放在了router.js裡面了,所以在main.js中,引入的是router.js。但是現在,router.js裡面只放路由配置,其他的內容全部都放在了index.js裡面了,包括路由暴露,所以還需要修改main.js。
路由巢狀
現在假設專案有兩個模組:首頁和新聞模組,而新聞模組包括one、two、thr三個子模組。那麼在路由設定上,就需要設定兩個一級路由:home和news,然後news下面再新增三個子路由,這就是路由巢狀。
為了實現路由巢狀,首先對專案進行相應的改變:將one.vue、two.vue和thr.vue恢復為最基本的初始結構,然後新增一個標題:
然後在page資料夾下面新增home.vue和news.vue
接下來配置路由,只需要修改router.js就可以了
最後只需要在App.js中新增路由導航和佔位符就可以了。
到現在,只是實現了基本的路由跳轉
接下來才是路由巢狀
首先配置路由,因為三個新聞頁面都是新聞模組的子模組,所以需要將路由配置在news裡面
然後需要將路由導航和路由出口放置在父級路由頁面中,這裡是news.vue
history模式
在前面所以的演示中,我們會發現位址列中都會帶有#,而不是平常所看到的那種路由,這是因為使用hash模式,在vue中,路由有兩種模式,hash模式和history模式,預設是hash模式,url使用#後面定位路由,對SEO不利。
所以,我們可以採用history模式,只需要在router資料夾下面的index.js進行簡單設定就可以了。
但是,使用這種模式也會問題的,如果使用history模式,那麼打包後的專案只能放在伺服器的根目錄,否則會報錯,試過很多次,還沒有找到好的解決辦法額。
程式碼下載:點這裡
路由守衛
全域性守衛
在實際工作,為了保證系統的安全性,使用者必須成功登入以後才能瀏覽系統中的其他頁面,例如,在上面的例子,將Home頁面改為登入頁,使用者只要登入後,才能看到新聞,也就是說,在路由跳轉前,需要進行一個判斷,該使用者是否登入了。
為了表示登入,在使用者登入後,在本地儲存一個token
這樣,只要每次進行路由跳轉前,判斷本地是否儲存有token,就能知道使用者是否登入了,但是如果在每個路由跳轉的地方新增一次判斷,是不太現實的,所以,需要使用router.beforeEach實現全域性路由守衛,也就是每次路由跳轉前,都會走這個方法。
其中/home?redirect='+to.path的作用是記錄當前想要去的頁面,然後跳轉到登入頁進行登入成功後,會直接進入這個頁面。
beforeEach的三個引數分別表示:
-
from: Route
: 當前導航正要離開的路由 -
next: Function
: 一定要呼叫該方法來 resolve 這個鉤子。執行效果依賴next
方法的呼叫引數。
獨享守衛
當然了,除了為所有的路由統一新增路由守衛外,還可以單獨為某個路由新增獨有的路由守衛。
元件內守衛
元件內的守衛,主要有三個beforeRouteEnter()、beforeRouteUpdate()、beforeRouteLeave()
用法和beforeEach是一樣的。
關於這三個,官方文件給出的解釋如下:
程式碼下載:點這裡