vue-router中的鉤子函數和執行順序說明
一:全局導航鉤子函數
1、vue router.beforeEach(全局前置守衛)
beforeEach的鉤子函數,它是一個全局的before 鉤子函數, (before each)意思是在 每次每一個路由改變的時候都得執行一遍。
它的三個參數:
to
: (Route路由對象) 即將要進入的目標 路由對象 to對象下面的屬性: path params query hash fullPath matched name meta(在matched下,但是本例可以直接用)from
: (Route路由對象) 當前導航正要離開的路由next
: (Function函數) 一定要調用該方法來 resolve 這個鉤子。 調用方法:next(參數或者空) ***必須調用- next(無參數的時候): 進行管道中的下一個鉤子,如果走到最後一個鉤子函數,那麼 導航的狀態就是 confirmed (確認的)
- next('/') 或者 next({ path: '/' }): 跳轉到一個不同的地址。當前的導航被中斷,然後進行一個新的導航。
- 應用場景:可進行一些頁面跳轉前處理,例如判斷需要登錄的頁面進行攔截,做登錄跳轉!!
router.beforeEach((to, from, next) => { if (to.meta.requireAuth) { //判斷該路由是否需要登錄權限 if (cookies('token')) { //通過封裝好的cookies讀取token,如果存在,name接下一步如果不存在,那跳轉回登錄頁 next()//不要在next裡面加"path:/",會陷入死循環 } else { next({ path: '/login', query: {redirect: to.fullPath}//將跳轉的路由path作為參數,登錄成功後跳轉到該路由 }) } } else { next() } })
應用場景,進入頁面登錄判斷、管理員權限判斷、瀏覽器判斷
//使用鉤子函數對路由進行權限跳轉 router.beforeEach((to, from, next) => { const role = localStorage.getItem('ms_username'); if(!role && to.path !== '/login'){ next('/login'); }else if(to.meta.permission){ // 如果是管理員權限則可進入,這裡隻是簡單的模擬管理員權限而已 role === 'admin' ? next() : next('/403'); }else{ // 簡單的判斷IE10及以下不進入富文本編輯器,該組件不兼容 if(navigator.userAgent.indexOf('MSIE') > -1 && to.path === '/editor'){ Vue.prototype.$alert('vue-quill-editor組件不兼容IE10及以下瀏覽器,請使用更高版本的瀏覽器查看', '瀏覽器不兼容通知', { confirmButtonText: '確定' }); }else{ next(); } } })
2、vue router.afterEach(全局後置守衛)
router.beforeEach 是頁面加載之前,相反router.afterEach是頁面加載之後
二:路由獨享的守衛(路由內鉤子)
你可以在路由配置上直接定義 beforeEnter 守衛:
const router = new VueRouter({ routes: [ { path: '/foo', component: Foo, beforeEnter: (to, from, next) => { // ... } } ]
這些守衛與全局前置守衛的方法參數是一樣的。
三:組件內的守衛(組件內鉤子)
1、beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave
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` }
2、路由鉤子在實際開發中的應用場景
(一) 清除當前組件中的定時器
當一個組件中有一個定時器時, 在路由進行切換的時候, 可使用beforeRouteLeave將定時器進行清楚, 以免占用內存:
beforeRouteLeave (to, from, next) { window.clearInterval(this.timer) //清楚定時器 next() }
(二) 當頁面中有未關閉的窗口, 或未保存的內容時, 阻止頁面跳轉
如果頁面內有重要的信息需要用戶保存後才能進行跳轉, 或者有彈出框的情況. 應該阻止用戶跳轉,結合vuex狀態管理(dialogVisibility是否有保存)
beforeRouteLeave (to, from, next) { //判斷是否彈出框的狀態和保存信息與否 if (this.dialogVisibility === true) { this.dialogVisibility = false //關閉彈出框 next(false) //回到當前頁面, 阻止頁面跳轉 }else if(this.saveMessage === false) { alert('請保存信息後退出!') //彈出警告 next(false) //回到當前頁面, 阻止頁面跳轉 }else { next() //否則允許跳轉 }
(三) 保存相關內容到Vuex中或Session中
當用戶需要關閉頁面時, 可以將公用的信息保存到session或Vuex中
beforeRouteLeave (to, from, next) { localStorage.setItem(name, content); //保存到localStorage中 next() }
vue-router執行順序
- 導航被觸發。
- 在失活的組件裡調用 beforeRouteLeave 守衛。
- 調用全局的 beforeEach 守衛。
- 在重用的組件裡調用 beforeRouteUpdate 守衛 (2.2+)。
- 在路由配置裡調用 beforeEnter。
- 解析異步路由組件。
- 在被激活的組件裡調用 beforeRouteEnter。
- 調用全局的 beforeResolve 守衛 (2.5+)。
- 導航被確認。
- 調用全局的 afterEach 鉤子。
- 觸發 DOM 更新。
- 調用 beforeRouteEnter 守衛中傳給 next 的回調函數,創建好的組件實例會
- 作為回調函數的參數傳入。
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- 快速理解Vue路由導航守衛
- vue-router鉤子函數實現路由守衛
- 關於Vue Router的10條高級技巧總結
- Vue router 路由守衛詳解
- vue的路由守衛和keep-alive後生命周期詳解