iT邦幫忙

2021 iThome 鐵人賽

DAY 20
0
Modern Web

Vue.js 什麼意思系列 第 20

Day 20:全域、路由、元件內-Navigation Guards

之前有預告過,發送 API 的時機點需視不同情境及 UX 體驗規劃而定,因此除了選擇在元件內的生命週期 created 發送,另外在 Vue Router 還有像警衛一般的「導航守衛(Navigation Guards)」,分別可以駐守在全域、路由和元件內。

在導航守衛文件的最底部,已先整理出 Resolution Flow 讓我們知道3種守衛位置、7個守衛時機的先後順序,以便根據專案需求在合適的時間點發送 API 或執行其他動作。

Navigation Guards
(圖片來源:Vue Router - Navigation Guards - The Full Navigation Resolution Flow

三種守衛位置分別在趨近目標路由的過程中慢慢收斂守衛範圍,由大至小分別是在全域、路由、元件內調用。

導航守衛接收參數:to、from、next

  • to:即將進入的目標路由
  • from:準備離開的上個路由
  • next(必選):繼續執行的 callback 函式,必須呼叫 next() 才會執行下一步;因此在所有導航守衛中為必選程序,在同一個導航守衛中可使用一或多次

全域設置 Global Resolve Guards

  • beforeEach:進入每個路由之前

  • beforeResolve:在路由完成跳轉之前,但所有元件內守衛和路由元件已完成解析

  • afterEach:每個路由完成跳轉之後

  • 應用範例:登入系統需要驗證會員身份,部分路徑內容會根據使用者身份限制瀏覽範圍或操作行為,例如成為正式會員之後才能在網站內進行購買商品。因此會選擇在全域 beforeEach 進入每一個路由之前就先判斷會員目前的狀態,若該路徑僅限於會員才能進入,就會將使用者導向登入頁面,引導使用者註冊為會員。

    routes 中的每個路由物件稱為 route record,通常會搭配設置 Route Meta 限制個別路由的權限,並在每次進入路由之前先判斷 route record 所設置的 meta 狀態,再做接下來的導向流程。

    const router = new VueRouter({
      routes: [
        {
            path: "/member",
            redirect: { name: "Profile" },
            component: MemberPage,
            children: [
              {
                path: "collection",
                name: "Collection",
                component: Collection,
              },
              {
                path: "collection/purchase/:bookName",
                name: "Purchase",
                component: Purchase,
                meta: { requiresAuth: true } // 設為需為登入狀態
              },
            ],
          }
      ]
    })
    
    // 全域設置進入路由之前的時間點
    router.beforeEach((to, from, next) => {
      // 當路由物件的 meta 設有 requiresAuth 時
      if (to.matched.some(record => record.meta.requiresAuth)) {
    	// 尚未登入
        if (!Token) {
          next({ path: '/login' }) // 導向登入頁面
        } else {
          next() // 登入成功,則可繼續往下執行
        }
      } else {
        next() // 確保一定要使用 next()
      }
    })
    

路由設置 Per-Route Guard

  • beforeEnter:準備進入單一路由之前
  • 應用範例:進入首頁之前需要取得輪播圖資料,而進入產品列表時則需要取得所有產品清單,這些資料都僅針對滿足單一路由的需求即可,因此只需要在該路由設置 beforeEnter,不會影響到其他路由。

元件設置 In-Component Guards

  • beforeRouteEnter:路由進入元件之前
  • beforeRouteUpdate:具有相同元件的路由發生更新時
  • beforeRouteLeave:路由離開元件之前
  • 應用範例:動態路由通常會有重複使用元件的情形,造成切換路由頁面只會是單純切換路徑,但是並不會更新畫面,因此需在元件內調用 beforeRouteUpdate 發送 API 即時接收資料,才能在路由切換之後重新接收資料並渲染至畫面上。

參考資料


上一篇
Day 19:有名模組,無限輔助-Vuex Modules、Map Helper
下一篇
Day 21:總匯複習-Vuex、Route
系列文
Vue.js 什麼意思30

尚未有邦友留言

立即登入留言