首頁 > 軟體

vue-router中的勾點函數和執行順序說明

2022-07-02 14:00:21

一:全域性導航勾點函數

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 的回撥函數,建立好的元件範例會
  • 作為回撥函數的引數傳入。

以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。 


IT145.com E-mail:sddin#qq.com