91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Vue如何二次封裝axios為插件使用

發布時間:2021-08-10 11:12:07 來源:億速云 閱讀:154 作者:小新 欄目:web開發

這篇文章給大家分享的是有關Vue如何二次封裝axios為插件使用的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

vuejs2.0 已經不再維護 vue-resource,vuejs2.0 已經使用了 axios,這也是為什么我會轉到 axios 的主要原因

基本的封裝要求:

  1. 統一 url 配置

  2. 統一 api 請求

  3. request (請求)攔截器,例如:帶上token等,設置請求頭

  4. response (響應)攔截器,例如:統一錯誤處理,頁面重定向等

  5. 根據需要,結合 Vuex 做全局的loading動畫,或者錯誤處理

  6. 將 axios 封裝成 Vue 插件使用

文件結構

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

src

  |

-- http 封裝axios模塊文件夾

   |

---- config.js axios的默認配置

---- api.js 二次封裝axios,攔截器等

---- interface.js 請求接口文件

---- index.js 將axios封裝成插件

config.js

默認配置參照 gitHub,以下只做示例:

export default {
  method: 'post',
  // 基礎url前綴
  baseURL: 'https://easy-mock.com/mock/5ad75e9f41d4d65f0e935be4/example',
  // 請求頭信息
  headers: {
   'Content-Type':'application/json;charset=UTF-8'
  },
  // 參數
  data: {},
  // 設置超時時間
  timeout: 10000,
  // 攜帶憑證
  withCredentials: false,
  // 返回數據類型
  responseType: 'json'
}

PS: 這里推薦一下一款 Mock 工具Easy Mock,以上請求地址來自該工具。以后有空會單獨寫一下怎么使用該工具。

api.js

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 '':
        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)
    })
  })
}

interface.js

import axios from './api' // 倒入 api

/* 將所有接口統一起來便于維護
 * 如果項目很大可以將 url 獨立成文件,接口分成不同的模塊
 * 此處的數據依然來自 Easy Mock
 */

// 單獨倒出
export const query = params => {
  return axios({
    url: '/query',
    method: 'get',
    params
  })
}
 
export const mock = params => {
  return axios({
    url: '/mock',
    method: 'get',
    params
  })
}

export const upload = data => {
  return axios({
    url: '/upload',
    method: 'post',
    data
  })
}

// 默認全部倒出
// 根絕需要進行 
export default {
  query,
  mock,
  upload
}

index.js

封裝成 Vue 插件,便(提)于(高)使(B)用(格)

// 倒入所有接口
import apiList from './interface'

const install = Vue => {
  if (install.installed) 
    return;
  install.installed = true;

  Object.defineProperties(Vue.prototype, {
    // 注意哦,此處掛載在 Vue 原型的 $api 對象上
    $api: {
      get() {
        return apiList
      }
    }
  })
}

export default install

使用

到此為止,萬事俱備就差用了,在 mian.js 中做如下操作:

// 倒入 http 文件夾下的 index.js
import api from './http/index'
Vue.use(api)

// 此時可以直接在 Vue 原型上調用 $api 了

總結

  1. 以上二次封裝較為全面,基本完成了我們之前的需求

  2. 在錯誤的處理上還需要與后端協定好返回值,做具體的約定

  3. 封裝回調有點多,在使用的時候也需要加上 then() 來處理結果,async & await 了解一下喲,好東西當然要藏起來,我才不會分享出來呢...

PS: IE9 不支持 Promise 哦,需要安裝一個 polyfill

import 'babel-polyfill'

感謝各位的閱讀!關于“Vue如何二次封裝axios為插件使用”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

湘阴县| 成都市| 广饶县| 孙吴县| 平利县| 嵊州市| 自治县| 株洲县| 同德县| 漠河县| 武城县| 靖安县| 新乡市| 梅州市| 江永县| 五莲县| 湖南省| 南雄市| 许昌县| 兴国县| 当阳市| 仪征市| 武清区| 永仁县| 浦北县| 抚宁县| 昆明市| 临安市| 清涧县| 五大连池市| 稻城县| 辉县市| 淮阳县| 祥云县| 资中县| 东乡| 东丽区| 辽中县| 盐源县| 民丰县| 彰化市|