Vue2學習小記-給Vue2路由導航鉤子和axios攔截器作個封裝

1.寫在前面

最近在學習Vue2,遇到有些頁面請求數據須要用戶登陸權限、服務器響應不符預期的問題,可是總不能每一個頁面都作單獨處理吧,因而想到axios提供了攔截器這個好東西,再因而就出現了本文。vue

2.具體需求

  • 用戶鑑權與重定向:使用Vue提供的路由導航鉤子
  • 請求數據序列化:使用axios提供的請求攔截器
  • 接口報錯信息處理:使用axios提供的響應攔截器

3.簡單實現

3.1 路由導航鉤子層面鑑權與重定向的封裝

路由導航鉤子全部配置均在router/index.js,這裏是部分代碼ios

import Vue from 'vue'
import Router from 'vue-router'
import { getUserData } from '@/script/localUserData'

const MyAddress = r => require.ensure([], () => r(require('@/views/MyAddress/MyAddress')), 'MyAddress')

Vue.use(Router)

const routes = [
  {
    path: '/profile/address',
    name: 'MyAddress',
    component: MyAddress,
    meta: {
      title: '個人地址',
      requireAuth: true
    }
  },
  // 更多...
]

const router = new Router({
  mode: 'history',
  routes
})

咱們主要來看下面邏輯處理部分的代碼git

let indexScrollTop = 0
router.beforeEach((to, from, next) => {
  // 路由進入下一個路由對象前,判斷是否須要登錄
  // 在路由meta對象中由個requireAuth字段,只要此字段爲true,必須作鑑權處理
  if (to.matched.some(res => res.meta.requireAuth)) {
    // userData爲存儲在本地的一些用戶信息
    let userData = getUserData()
    // 未登陸和已經登陸的處理
    // getUserData方法處理後若是userData.token沒有值就是undefined,下面直接判斷
    if (userData.token === undefined) {
      // 執行到此處說明沒有登陸,君可按需處理以後再執行以下方法去登陸頁面
      // 我這裏沒有其餘處理,直接去了登陸頁面
      next({
        path: '/login',
        query: {
          redirect: to.path
        }
      })
    } else {
      // 執行到說明本地存儲有用戶信息
      // 可是用戶信息是否過時仍是須要驗證一下滴
      let overdueTime = userData.overdueTime
      let nowTime = +new Date
      // 登錄過時和未過時
      if (nowTime > overdueTime) {
        // 登陸過時的處理,君可按需處理以後再執行以下方法去登陸頁面
        // 我這裏沒有其餘處理,直接去了登陸頁面
        next({
          path: '/login',
          query: {
            redirect: to.path
          }
        })
      } else {
        next()
      }
    }
  } else {
    next()
  }
  if (to.path !== '/') {
    indexScrollTop = document.body.scrollTop
  }
  document.title = to.meta.title || document.title
})

router.afterEach(route => {
  if (route.path !== '/') {
    document.body.scrollTop = 0
  } else {
    Vue.nextTick(() => {
      document.body.scrollTop = indexScrollTop
    })
  }
})
export default router

至此,路由鉤子層面的鑑權處理完畢,不過細心的你可能注意到:導航去登陸頁面調用的next方法裏面有個query對象,攜帶了目標路由的地址,這是由於在登陸成功後咱們須要重定向到目標頁面。github

3.2 對axios攔截器封裝

axios全部配置均在件script/getData.js文件,這裏是本文件公共代碼部分vue-router

import qs from 'qs'
import { getUserData } from '@/script/localUserData'
import router from '@/router'
import axios from 'axios'
import { AJAX_URL } from '@/config/index'
axios.defaults.baseURL = AJAX_URL

axios請求攔截器代碼axios

/**
* 請求攔截器,請求發送以前作些事情
*/
axios.interceptors.request.use(
 config => {
   // POST || PUT || DELETE請求時先格式化data數據
   // 這裏須要引入第三方模塊qs
   if (
     config.method.toLocaleUpperCase() === 'POST' ||
     config.method.toLocaleUpperCase() === 'PUT' ||
     config.method.toLocaleUpperCase() === 'DELETE'
   ) {
     config.data = qs.stringify(config.data)
   }
   // 配置Authorization參數攜帶用戶token
   let userData = getUserData()
   if (userData.token) {
     config.headers.Authorization = userData.token
   }
   return config
 },
 error => {
   // 此處應爲彈窗顯示具體錯誤信息,由於是練手項目,劣者省略此處
   // 君可自行寫 || 引入第三方UI框架
   console.error(error)
   return Promise.reject(error)
 }
)

axios響應攔截器代碼後端

/**
 * 響應攔截器,請求返回異常統一處理
 */
axios.interceptors.response.use(
  response => {
    // 這段代碼不少場景下沒用
    if (response.data && response.data.success === false) {
      // 根據實際狀況的一些處理邏輯...
      return Promise.reject(response)
    }
    return response
  },
  error => {
    // 此處報錯可能因素比較多
    // 1.須要受權處用戶還未登陸,由於路由段有驗證是否登錄,此處理論上不會出現
    // 2.須要受權處用戶登登陸過時
    // 3.請求錯誤 4xx
    // 5.服務器錯誤 5xx
    // 關於鑑權失敗,與後端約定狀態碼爲500
    switch (error.response.status) {
      case 403:
        // 一些處理...
        break
      case 404:
        // 一些處理...
        break
      case 500:
        let userData = getUserData()
        if (userData.token === undefined) {
          // 此處爲未登陸處理
          // 一些處理以後...再去登陸頁面...
          // router.push({
          //   path: '/login'
          // })
        } else {
          let overdueTime = userData.overdueTime
          let nowTime = +new Date
          if (overdueTime && nowTime > overdueTime) {
            // 此處登陸過時的處理
            // 一些處理以後...再去登陸頁面...
            // router.push({
            //   path: '/login'
            // })
          } else {
            // 極端狀況,登陸未過時,可是不知道哪兒錯了
            // 按需處理吧...我暴力回到了首頁
            router.push({
              path: '/'
            })
          }
        }
        break
      case 501:
        // 一些處理...
        break
      default:
        // 狀態碼辣麼多,按需配置...
        break
    }
    return Promise.reject(error)
  }
)

想了解更多關於axios的信息?請移步這裏服務器

這個封裝很簡單,面對複雜的業務確定還須要更多的考量,可是對於通常的小項目或邊緣業務也差很少夠用了。最後但願這篇文章能對有須要的同窗提供一些幫助。框架

相關文章
相關標籤/搜索