Vue二次封裝axios爲插件使用

vuejs2.0 已經再也不維護 vue-resource,vuejs2.0 已經使用了 axios,這也是爲何我會轉到 axios 的主要緣由,廢話很少說: 基本的封裝要求:css

  • 統一 url 配置
  • 統一 api 請求
  • request (請求)攔截器,例如:帶上token等,設置請求頭
  • response (響應)攔截器,例如:統一錯誤處理,頁面重定向等
  • 根據須要,結合 Vuex 作全局的loading動畫,或者錯誤處理
  • 將 axios 封裝成 Vue 插件使用

文件結構 使用 vue-cli 進行相關的封裝,在 src 文件夾下:html

src 
| 
-- http 封裝axios模塊文件夾
| 
---- config.js axios的默認配置
---- api.js 二次封裝axios,攔截器等 
---- interface.js 請求接口文件 
---- index.js 將axios封裝成插件
複製代碼

config.js 默認配置參照 gitHub,如下只作示例:前端

export default {
  method: 'post',
  // 基礎url前綴
  baseURL: 'http://qm.qq.com/cgi-bin/qm/qr?k=7aFQitBKLfNUDg3JDbAll697s4MzVV4n',
  // 請求頭信息
  headers: {
   'Content-Type':'application/json;charset=UTF-8'
  },
  // 參數
  data: {},
  // 設置超時時間
  timeout: 10000,
  // 攜帶憑證
  withCredentials: false,
  // 返回數據類型
  responseType: 'json'
}
複製代碼

api.jsvue

import axios from 'axios' // 注意先安裝哦
import config from './config.js' // 倒入默認配置
import qs from 'qs' // 序列化請求數據,視服務端的要求
 
export default function $axios (options) {
  return new Promise((resolve, reject) => {
    const instance = axios.create({
      baseURL: config.baseURL,
      headers: {},
      transformResponse: [function (data) {}]
    }
  )
 
  // request 攔截器
  instance.interceptors.request.use(
    config => {
      // Tip: 1
      // 請求開始的時候能夠結合 vuex 開啓全屏的 loading 動畫
 
      // Tip: 2 
      // 帶上 token , 能夠結合 vuex 或者重 localStorage
      // if (store.getters.token) {
      //   config.headers['X-Token'] = getToken() // 讓每一個請求攜帶token--['X-Token']爲自定義key 請根據實際狀況自行修改
      // } else {
      //   // 重定向到登陸頁面  
      // }
 
      // Tip: 3
      // 根據請求方法,序列化傳來的參數,根據後端需求是否序列化
      if (config.method.toLocaleLowerCase() === 'post'
        || config.method.toLocaleLowerCase() === 'put'
        || config.method.toLocaleLowerCase() === 'delete') {
 
        config.data = qs.stringify(config.data)
      }
      return config
    },
    error => {
      // 請求錯誤時作些事(接口錯誤、超時等)
      // Tip: 4
      // 關閉loadding
      console.log('request:', error) 
     
      // 1.判斷請求超時
      if (error.code === 'ECONNABORTED' && error.message.indexOf('timeout') !== -1) {
        console.log('根據你設置的timeout/真的請求超時 判斷請求如今超時了,你能夠在這裏加入超時的處理方案')
        // return service.request(originalRequest);//例如再重複請求一次
      }
      // 2.須要重定向到錯誤頁面
      const errorInfo = error.response
      console.log(errorInfo)
      if (errorInfo) {
        // error =errorInfo.data//頁面那邊catch的時候就能拿到詳細的錯誤信息,看最下邊的Promise.reject
        const errorStatus = errorInfo.status; // 404 403 500 ... 等
        router.push({
          path: `/error/${errorStatus}`
        })
      }
      return Promise.reject(error) // 在調用的那邊能夠拿到(catch)你想返回的錯誤信息
    }
  )
  
  // response 攔截器
  instance.interceptors.response.use(
    response => {
      let data;
      // IE9時response.data是undefined,所以須要使用response.request.responseText(Stringify後的字符串)
      if(response.data == undefined){
        data = response.request.responseText
      } else{
        data = response.data
      }
      // 根據返回的code值來作不一樣的處理(和後端約定)
      switch (data.code) {
        case ''://歡迎加入全棧開發交流圈一塊兒學習交流:864305860
        break;//幫助突破技術瓶頸,提高思惟能力
        default:
      }
      // 若不是正確的返回code,且已經登陸,就拋出錯誤
      // const err = new Error(data.description)
 
      // err.data = data
      // err.response = response
 
      // throw err
      return data
    },
    err => {
      if (err && err.response) {
        switch (err.response.status) {
          case 400:
          err.message = '請求錯誤'
          break
       
          case 401:
          err.message = '未受權,請登陸'
          break
       
          case 403:
          err.message = '拒絕訪問'
          break
       
          case 404:
          err.message = `請求地址出錯: ${err.response.config.url}`
          break
       
          case 408:
          err.message = '請求超時'
          break
       
          case 500:
          err.message = '服務器內部錯誤'
          break
       
          case 501:
          err.message = '服務未實現'
          break
       
          case 502:
          err.message = '網關錯誤'
          break
       
          case 503:
          err.message = '服務不可用'
          break
       
          case 504:
          err.message = '網關超時'
          break
       
          case 505:
          err.message = 'HTTP版本不受支持'
          break
       
          default:
        }
      }
      console.error(err)
      // 此處我使用的是 element UI 的提示組件
      // Message.error(`ERROR: ${err}`);
      return Promise.reject(err) // 返回接口返回的錯誤信息
    }
  )
  
  //請求處理
  instance(options)
    .then((res) => {
      resolve(res)
      return false
    })
    .catch((error) => {
      reject(error)
    })//歡迎加入全棧開發交流圈一塊兒學習交流:864305860
  })//面向1-3年前端人員
}//幫助突破技術瓶頸,提高思惟能力
複製代碼

interface.jsnode

import axios from './api' // 倒入 api
 
/* 將全部接口統一塊兒來便於維護
 * 若是項目很大能夠將 url 獨立成文件,接口分紅不一樣的模塊
 * 此處的數據依然來自 Easy Mock
 */
 
// 單獨倒出
export const query = params => {
  return axios({
    url: '/query',
    method: 'get',
    params
  })//歡迎加入全棧開發交流圈一塊兒學習交流:864305860
}
export const mock = params => {
  return axios({
    url: '/mock',
    method: 'get',
    params
  })//歡迎加入全棧開發交流圈一塊兒學習交流:864305860
} 
export const upload = data => {
  return axios({
    url: '/upload',
    method: 'post',
    data
  })//歡迎加入全棧開發交流圈一塊兒學習交流:864305860
}
// 默認所有倒出
// 根絕須要進行 
export default {
  query,
  mock,
  upload
}//歡迎加入全棧開發交流圈一塊兒學習交流:864305860
複製代碼

index.js 封裝成 Vue 插件,便(提)於(高)使(B)用(格)webpack

// 倒入全部接口
import apiList from './interface' 
const install = Vue => {
  if (install.installed) 
    return;
  install.installed = true; 
  Object.defineProperties(Vue.prototype, {
    // 注意哦,此處掛載在 Vue 原型的 $api 對象上
    $api: {
      get() {
        return apiList
      }//歡迎加入全棧開發交流圈一塊兒學習交流:864305860
    }//面向1-3年前端人員
  })//幫助突破技術瓶頸,提高思惟能力
} 
export default install
複製代碼

使用 到此爲止,萬事俱備就差用了,在 mian.js 中作以下操做:ios

// 倒入 http 文件夾下的 index.js
import api from './http/index'
Vue.use(api)
 
// 此時能夠直接在 Vue 原型上調用 $api複製代碼

總結git

  • 以上二次封裝較爲全面,基本完成了咱們以前的需求
  • 在錯誤的處理上還須要與後端協定好返回值,作具體的約定
  • 封裝回調有點多,在使用的時候也須要加上 then() 來處理結果

PS: IE9 不支持 Promise 哦,須要安裝一個 polyfill import 'babel-polyfill'web

本次給你們推薦一個免費的學習羣,裏面歸納移動應用網站開發,css,html,webpack,vue node angular以及面試資源等。 對web開發技術感興趣的同窗,歡迎加入Q羣:864305860,無論你是小白仍是大牛我都歡迎,還有大牛整理的一套高效率學習路線和教程與您免費分享,同時天天更新視頻資料。 最後,祝你們早日學有所成,拿到滿意offer,快速升職加薪,走上人生巔峯。面試

相關文章
相關標籤/搜索