導航守衛的理解和使用


1、導航守衛鈎子

導航守衛的用途主要是在用戶離開頁面前提醒用戶,和頁面訪問前先登錄。共有7個鈎子,其中全局鈎子有3個,組件鈎子有3個,路由管道鈎子有1個。

全局鈎子:

const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
    // ...(2)
    //全局前置守衛
})
router.beforeResolve((to, from, next) => {
   // ...(6)
    //全局解析守衛

})
router.afterEach((to, from) => {
  // ...(7)
  //全局后置守衛
}

組件內的鈎子:

export default {
  data(){},
  beforeRouteEnter (to, from, next) {
    //....(5)
    // 在渲染該組件的對應路由被 confirm 前調用
    // 不!能!獲取組件實例 `this`
    // 因為當守衛執行前,組件實例還沒被創建
  },
  beforeRouteUpdate (to, from, next) {
    // ... (3)
    // 在當前路由改變,但是該組件被復用時調用
    // 舉例來說,對於一個帶有動態參數的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉的時候,
    // 由於會渲染同樣的 Foo 組件,因此組件實例會被復用。而這個鈎子就會在這個情況下被調用。
    // 可以訪問組件實例 `this`
  },
  beforeRouteLeave (to, from, next) {
    // ... (1)
    // 導航離開該組件的對應路由時調用
    // 可以訪問組件實例 `this`
  }
}

路由管道鈎子:

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => {
        // ...(4)
      }
    }
  ]
})

2、參數解析

每個守衛方法接收三個參數:

  • to: Route: 即將要進入的目標 路由對象,該對象有目標頁的路由信息。

  • from: Route: 當前導航正要離開的路由,該對象有當前頁的路由信息。

  • next: Function: 一定要調用該方法來 resolve 這個鈎子。執行效果依賴 next 方法的調用參數。

    • next(): 進行管道中的下一個鈎子。如果全部鈎子執行完了,則導航的狀態就是 confirmed (確認的)。

    • next(false): 中斷當前的導航。如果瀏覽器的 URL 改變了 (可能是用戶手動或者瀏覽器后退按鈕),那么 URL 地址會重置到 from 路由對應的地址。

    • next('/') 或者 next({ path: '/' }): 跳轉到一個不同的地址。當前的導航被中斷,然后進行一個新的導航。你可以向 next 傳遞任意位置對象,且允許設置諸如 replace: truename: 'home' 之類的選項以及任何用在 router-link 的 to prop 或 router.push 中的選項。

    • next(error): (2.4.0+) 如果傳入 next 的參數是一個 Error 實例,則導航會被終止且該錯誤會被傳遞給 router.onError() 注冊過的回調。

確保要調用 next 方法,否則鈎子就不會被 resolved。

3、導航流程

  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 的回調函數。

4、導航流程圖(頁面切換的執行順序)

5、頁面跳轉前需登錄  - 實驗

 1)首先需要給isLogin為false,表示未登錄,將該值初始在store內,

export default new Vuex.Store({
  state: {
    isLogin: false,
  },
  mutations: {
    handleLogin(state, login) {
      state.isLogin = login;
    },
  },
});

 

 2)在登錄頁- 登錄按鈕 設置點擊時修改store內的isLogin為true,同時跳轉到首頁‘/home’

methods: {
    ...mapMutations(['handleLogin']),
    handleSubmit() {
      // 修改store里的isLogin為true,表示登錄了 
      this.handleLogin(true)
      this.$router.push({path: '/home'})
    }
  }

 

 3)每一次頁面切換時,全局鈎子beforeEach都會觸發,在該鈎子內判斷 是否登錄了?若沒有登錄,需要跳轉到 登錄頁 ‘/login’,否則 可以跳轉 

router.beforeEach((to, from, next) => {
  const isLogin = obj.state.isLogin;
  if (to.path === '/login' || isLogin) {
    next();
  } else {
    next('/login');
  }
});

 6、參考文獻

https://router.vuejs.org/zh/guide/advanced/navigation-guards.html#%E5%85%A8%E5%B1%80%E5%89%8D%E7%BD%AE%E5%AE%88%E5%8D%AB

https://www.cnblogs.com/minigrasshopper/p/7928311.html

 

route


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM