你可能不清楚的 Vue Router 深度用法(一)

Vue Router 簡單易上手,能實現大部分的需求。可是,若是在項目裏須要更細緻的控制路由,以實現與其同步的效果,就須要挖掘其文檔裏沒詳細說起的內容。第一章爲路由元信息用途挖掘。

路由元信息用途

(1)驗證用戶身份

大部分項目,除了登陸頁、重置密碼頁、用戶協議頁之外,頁面都須要驗證用戶身份進行訪問。使用 Vue Router 能夠配合後端進行雙重驗證。前端


(登陸)驗證身份方法:ios

一、給須要驗證的路由對象添加 meta 字段,裏面自定義一個表明驗證的字段:axios

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      children: [
        {
          path: 'bar',
          component: Bar,
          meta: { 
              requiresAuth: true // 添加該字段,表示進入這個路由是須要登陸的
          }
        }
      ]
    }
  ]
})

二、在全局導航鉤子裏驗證 requiresAuth 字段:segmentfault

注意事項:後端

  • 使用 beforeEach 在路由變化前驗證。驗證原理是在跳轉前,訪問目標路由對象的 requiresAuth 字段判斷是否須要驗證用戶身份,如爲是,檢測是否有保存用戶信息(即用戶登陸成功後前端保存的信息,例如 token)
  • 每一個路由都有一個 $route.matched 數組,包含當前路由的父級路由對象和當前路由對象,在組件中能夠經過 this.$route.matched 訪問
  • beforeEach 的 to 參數即目標路由對象 $route,to.matched 便是它的路由數組
  • 所以,使用 some 方法,只要路由數組裏的任意路由對象須要驗證身份,即進行驗證
  • 驗證成功跳轉正確頁面;失敗則跳到登陸頁,將目標地址附在 url 的 query 裏,登陸成功就跳轉到目標地址
router.beforeEach((to, from, next) => {
  if (to.matched.some(record => record.meta.requiresAuth)) {
    if (!auth.loggedIn()) {  // 沒登陸
      next({
        path: '/login',
        query: { redirect: to.fullPath }
      })
    } else {
      next()  // 確保必定要調用 next()
    }
  } else {
    next() // 確保必定要調用 next()
  }
})

三、攔截 http 請求,驗證用戶身份數組

爲了防止本地保存的 token 過時,須要攔截 http 請求,爲每次請求頭加上 token ,而後攔截 http 響應,根據響應內容判斷是否須要跳回登陸頁面從新登陸。使用 axios 的方法以下:瀏覽器

// http request 攔截器
axios.interceptors.request.use(
    config => {
        if (auth.loggedIn()) { // 判斷是否存在token,若是存在的話,則每一個http header都加上token
            config.headers.Authorization = `token ${auth.loggedIn()}`;
        }
        return config;
    },
    err => {
        return Promise.reject(err);
    });

// http response 攔截器

axios.interceptors.response.use(
    response => {
        return response;
    },
    error => {
        if (error.response) {
            switch (error.response.status) {
                case 401:
                    // Unauthorized
                    // 返回 401 清除token信息並跳轉到登陸頁面
                    auth.clear();
                    router.replace({
                        path: 'login',
                        query: {
                            redirect: router.currentRoute.fullPath
                        }
                    })
            }
        }
        return Promise.reject(error.response.data) // 返回接口返回的錯誤信息
    });

(2)定義用戶權限能訪問的頁面

前端查看權限,也是配合後端進行某些頁面的隱藏顯示功能。通常應用於綜合的辦公系統,由 IT 部分配帳號,不一樣部門的人只能看到本身負責的內容,例如行政部不會看到財務數據頁面。ui

實現方法:this

  1. 與後端商定每一個用戶角色對應的 level 級別,以數值表示
  2. 前端路由每一個頁面的 meta 對象添加 level 字段,值爲數組,裏面是有權限訪問頁面的 level 數值
  3. 登陸成功,後臺返回用戶 token 的同時,返回其所屬的 level 字段
  4. 組件代碼比較目標頁面的 level 與用戶 level,只顯示包含在目標 level 數組裏的頁面
  5. 全局導航鉤子 beforeEach 裏比較目標頁面的 level 與用戶 level,包含在目標 level 數組裏則正確跳轉,反之取消跳轉並提示權限不足
上面第5步是爲了防止用戶直接在瀏覽器輸入目標地址

(3)其餘內容控制

能夠控制顯示路由固定的搭配,例如某個路由地址的 title 是固定的字符串、固定的歡迎語、固定的 favicon 等。在組件裏經過 this.$route.meta.xxx 訪問。url

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      children: [
        {
          path: 'bar',
          component: Bar,
          meta: { 
              title: '標題',
              message: '歡迎您',
              requiresAuth: true // 添加該字段,表示進入這個路由是須要登陸的
          }
        }
      ]
    }
  ]
})
第二章的內容在此 https://segmentfault.com/a/11...
相關文章
相關標籤/搜索