#在切換路由時,組件會被複用,不過,這也意味着組件的生命週期鉤子不會再被調用。vue
解決辦法有兩種,1簡單地 watch (監測變化) $route
對象:react
const User = { template: '...', watch: { '$route' (to, from) { // 對路由變化做出響應... } } }
2.使用 2.2 中引入的 beforeRouteUpdate
導航守衛:es6
const User = { template: '...', beforeRouteUpdate (to, from, next) { // react to route changes... // don't forget to call next() } }
#全局守衛vue-router
你可使用 router.beforeEach
註冊一個全局前置守衛:數組
const router = new VueRouter({ ... }) router.beforeEach((to, from, next) => { // ... })
to: Route
: 即將要進入的目標 路由對象異步
from: Route
: 當前導航正要離開的路由函數
next: Function
: 必定要調用該方法來 resolve 這個鉤子測試
#全局解析守衛ui
在 2.5.0+ 你能夠用 router.beforeResolve
註冊一個全局守衛。這和 router.beforeEach
相似,區別是在導航被確認以前,同時在全部組件內守衛和異步路由組件被解析以後,解析守衛就被調用。this
#全局後置鉤子
你也能夠註冊全局後置鉤子,然而和守衛不一樣的是,這些鉤子不會接受 next
函數也不會改變導航自己:
router.afterEach((to, from) => { // ... })
#路由獨享的守衛
你能夠在路由配置上直接定義 beforeEnter
守衛
const router = new VueRouter({ routes: [ { path: '/foo', component: Foo, beforeEnter: (to, from, next) => { // ... } } ] })
這些守衛與全局前置守衛的方法參數是同樣的。
#組件內的守衛
你能夠在路由組件內直接定義如下路由導航守衛:
const Foo = { template: `...`, beforeRouteEnter (to, from, next) { // 在渲染該組件的對應路由被 confirm 前調用 // 不!能!獲取組件實例 `this` // 由於當守衛執行前,組件實例還沒被建立 }, beforeRouteUpdate (to, from, next) { // 在當前路由改變,可是該組件被複用時調用 // 舉例來講,對於一個帶有動態參數的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉的時候, // 因爲會渲染一樣的 Foo 組件,所以組件實例會被複用。而這個鉤子就會在這個狀況下被調用。 // 能夠訪問組件實例 `this` }, beforeRouteLeave (to, from, next) { // 導航離開該組件的對應路由時調用 // 能夠訪問組件實例 `this` } }
beforeRouteEnter
守衛 不能 訪問 this
,由於守衛在導航確認前被調用,所以即將登場的新組件還沒被建立。
不過,你能夠經過傳一個回調給 next
來訪問組件實例。在導航被確認的時候執行回調,而且把組件實例做爲回調方法的參數。
export default { data(){ return { num: 18 } }, beforeRouteEnter(to, from, next){ next(vm=>{ vm.num=22; }) } }
注意 beforeRouteEnter
是支持給 next
傳遞迴調的惟一守衛。對於 beforeRouteUpdate
和 beforeRouteLeave
來講,this
已經可用了,因此不支持傳遞迴調,由於沒有必要了
#完整的導航解析流程
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 的回調函數。
#在全局導航守衛中檢查元字段
router.beforeEach((to, from, next) => { if (to.matched.some(record => record.meta.requiresAuth)) { //若是路由中有meta的requireAuth,且爲true,就不進行登陸驗證,不然進行登陸驗證 if (!auth.loggedIn()) { next({ path: '/login', query: { redirect: to.fullPath } }) } else { next() } } else { next() // 確保必定要調用 next() } })
一個路由匹配到的全部路由記錄會暴露爲 $route
對象 (還有在導航守衛中的路由對象) 的 $route.matched
數組。所以,咱們須要遍歷 $route.matched
來檢查路由記錄中的 meta
字段。
注:一、meta 字段就是路由元信息字段,requiresAuth 是本身起的字段名稱,用來標記這個路由信息是否須要檢測,true 表示要檢測,false 表示不須要檢測(這個名稱隨便起,好比我本身的就起的 requiresId,建議起個有意義的名稱)
二、if (to.matched.some(record => record.meta.requiresAuth) ),若是對這類寫法不熟悉,能夠去看看es6的箭頭函數,這句話就是返回遍歷的某個路由對象,咱們定義爲爲record,檢測這個對象是否擁有meta這個對象,若是有meta這個對象,檢測它的meta對象是否是有requiresAuth這個屬性,且爲true,若是知足上述條件,就肯定了是這個/foo/bar路由。
三、some() 方法測試數組中的某些元素是否經過了指定函數的測試。語法:arr.some(callback[, thisArg]);
some 爲數組中的每個元素執行一次 callback 函數,直到找到一個使得 callback 返回一個「真值」(便可轉換爲布爾值 true 的值)。若是找到了這樣一個值,some 將會當即返回 true。不然,some 返回 false。callback 只會在那些」有值「的索引上被調用,不會在那些被刪除或歷來未被賦值的索引上調用。
callback 被調用時傳入三個參數:元素的值,元素的索引,被遍歷的數組。
四、vue-router路由元信息說白了就是經過meta對象中的一些屬性來判斷當前路由是否須要進一步處理,若是須要處理,按照本身想要的效果進行處理便可!