Vue工程中單獨封裝axios攔截器


  之前項目的axios數據請求基本都是寫在各組件方法內,如項目接口變動要修改url地址等參數會比較為麻煩,不易維護,決定對axios進行封裝並將接口統一管理。

一、新建函數文件:

  在vue-cli工程內新建axios-request.js、axios-api.js,其中aixos-request.js用於對axios進行封裝,axios-api.js用於接口的統一管理,兩個的文件位置根據自身的工程目錄來定,我的是存放在src文件夾下的axios文件夾內。

二、對axios進行封裝:

// axios-request.js
import Vue from 'vue'
import Toast from 'muse-ui-toast' /* 引入muse-ui的Toast插件 */
import axios from 'axios'
import qs from 'qs' /* 引入qs依賴包,對傳參數據序列化 */
Vue.use(Toast, {
  time: 5000 /* 設置Toast顯示5s,防止用戶沒有注意到 */
})

/* 創建axios實例 */
const axiosService = axios.create({
  baseURL: process.env.API_HOST, /* 在config/dev.evn.js、prod.evn.js里面進行配置 */
  timeout: 5000 /* 設置超時時間為5s */
})

/* request攔截器 ==> 對請求參數進行處理 */
axiosService.interceptors.request.use(
  config => {
    config.method === 'post'
      ? config.data = qs.stringify({...config.data})
      : config.params = {...config.params}
      /* 判斷method是否為post,為post則對參數進行序列化,不為post擇不進行序列化 */
    config.headers['Content-Type'] = 'application/x-www-form-urlencoded'
    return config
  }, error => {
    Toast.error('錯誤,請重新操作...')
    Promise.reject(error)
  })

/* respone攔截器 ==> 對響應做處理 */
axiosService.interceptors.response.use(
  response => {
    if (response.data) {
      return response.data
    } else {
      Toast.error('數據錯誤,請重試...')
    }
  }, error => {
    /* 判斷error的status代碼,並將對應的信息告知用戶 */
    let text = ''
    let err = JSON.parse(JSON.stringify(error))
    if (err.response.status) {
      switch (error.response.status) {
        case 400:
          text = '請求錯誤(400),請重新申請'
          break
        case 401:
          text = '登錄錯誤(401),請重新登錄'
          return this.$router.replace('/Login')
        case 403:
          text = '拒絕訪問(403)'
          break
        case 404:
          text = '請求出錯(404)'
          break
        case 408:
          text = '請求超時(408)'
          break
        case 500:
          text = '服務器錯誤(500),請重啟軟件或切換功能頁!'
          break
        case 501:
          text = '服務未實現(501)'
          break
        case 502:
          text = '網絡錯誤(502)'
          break
        case 503:
          text = '服務不可用(503)'
          break
        case 504:
          text = '網絡超時(504)'
          break
        case 505:
          text = 'HTTP版本不受支持(505)'
          break
        default:
          text = '網絡連接出錯'
      }
    } else {
      text = '連接服務器失敗,請退出重試!'
    }
    Toast.error(text)
    return Promise.reject(error)
  }
)

/* 將寫好的axios實例暴露出去 */
export default axiosService

  這里使用了muse-uiToast插件用於用戶提示。

  如果后台需要前端發送時攜帶token,應在axiosService.interceptors.request.use的config內增加相關內容,我的項目中沒有運用到token,簡單的形式參考下面的代碼:

1 if (store.state.token) {  // 判斷是否存在token,如果存在的話,則每個http header都加上token
2             config.headers.Authorization = `token ${store.state.token}`;
3         }

三、對接口進行統一管理:

// axios-api.js
import axiosService from './axios-request' /* 從axios-request.js內引入axiosService */
 
/* 下面是POST形式 */
export const userLogin = data => {
  return axiosService({
    url: '/XXXX/user/xxxx', /* 根據實際接口地址來寫 */
    method: 'post',
    data
  })
}

/* 下面是GET形式 */
export const userInfo = params=> {
  return axiosService({
     url: '/XXXX/user/XXXXX.action',
     method: 'get',
     params
  })
}

  這里要注意下,post參數放在data內,get參數放在params內

四、在組件內使用寫好的接口:

下面是根據我的工程寫的一個登錄接口,僅供參考:

 1 import { userLogin } from '../../axios/axios-api' /* 引入登錄接口函數 */
 2 methods: {
 3     async login () {
 4       this.loginLoading = true
 5       let userName = this.userName
 6       let passWord = this.passWord
 7       let params = {
 8         username: userName,
 9         password: passWord
10       }
11       if (!userName || !passWord) {
12         this.loginLoading = false
13         this.$toast.error('賬號或密碼不能為空')
14       } else {
15         if ((userName.length < 51) && (passWord.length < 51)) {
16           let res = await userLogin(params)
17           this.loginBack(res)
18         } else {
19           this.loginLoading = false
20           this.$toast.error('賬號或密碼輸入字符不能超過50位')
21         }
22       }
23     },
24     loginBack (res) {
25       let resBack = res.Back
26       let resData = res.Data
27       if (resBack === '1') {
28         ......
29       } else {
30         ......
31       }
32     }
33   }

  使用這種方式,需要注意的是方法內的函數需要時用: async await格式

  當然也可以不將接口統一管理而只用axios封裝在組件內寫函數:

 1 import axiosService from '../../../../axios/axios-request' /* 這里直接引入axios封裝 */
 2 
 3 methods: {
 4     submitInfo () {
 5       let userName = localStorage.getItem('xyz')
 6       let dkId = this.nowLand.id
 7       let water = this.nowLand.water
 8       let status = this.nowLand.status
 9       let params = {
10         usename: userName,
11         dkid: dkId,
12         appwater: water
13       }
14       this.$confirm('是否提交申請?', '提示', {
15         type: 'warning'
16       }).then(({ result }) => {
17         if (result) {
18           if (status === 0) {
19            ......
20           } else {
21             axiosService({
22               url: '/HPGQ/waterrecord/addWaterRecord.action',
23               method: 'post',
24               params
25             }).then(this.applyBack)
26           }
27         } else {
28          ......
29         }
30       })
31     },
32     applyBack (res) {
33       ......
34     }
35   }

  以上是個人所用的封裝方式,如有錯誤之處歡迎留言指正~~


免責聲明!

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



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