最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue二次封裝axios為插件使用詳解

 更新時間:2018年05月21日 08:28:20   投稿:zx  
這篇文章主要介紹了Vue二次封裝axios為插件使用詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

照例先貼上 axios 的 gitHub 地址

不管用什么方式獲取數(shù)據(jù),對于一個項目來說,代碼一定要利于維護其次是一定要寫的優(yōu)美,因此加上一層封裝是必要的

vuejs2.0 已經(jīng)不再維護 vue-resource,vuejs2.0 已經(jīng)使用了 axios,這也是為什么我會轉(zhuǎn)到 axios 的主要原因,廢話不多說:

基本的封裝要求:

  1. 統(tǒng)一 url 配置
  2. 統(tǒng)一 api 請求
  3. request (請求)攔截器,例如:帶上token等,設(shè)置請求頭
  4. response (響應(yīng))攔截器,例如:統(tǒng)一錯誤處理,頁面重定向等
  5. 根據(jù)需要,結(jié)合 Vuex 做全局的loading動畫,或者錯誤處理
  6. 將 axios 封裝成 Vue 插件使用

文件結(jié)構(gòu)

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

src

  |

-- http 封裝axios模塊文件夾

   |

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

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

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

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

config.js

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

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

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

api.js

import axios from 'axios' // 注意先安裝哦
import config from './config.js' // 倒入默認配置
import qs from 'qs' // 序列化請求數(shù)據(jù),視服務(wù)端的要求

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
      // 請求開始的時候可以結(jié)合 vuex 開啟全屏的 loading 動畫

      // Tip: 2 
      // 帶上 token , 可以結(jié)合 vuex 或者重 localStorage
      // if (store.getters.token) {
      //   config.headers['X-Token'] = getToken() // 讓每個請求攜帶token--['X-Token']為自定義key 請根據(jù)實際情況自行修改
      // } else {
      //   // 重定向到登錄頁面  
      // }

      // Tip: 3
      // 根據(jù)請求方法,序列化傳來的參數(shù),根據(jù)后端需求是否序列化
      if (config.method.toLocaleLowerCase() === 'post' 
        || config.method.toLocaleLowerCase() === 'put' 
        || config.method.toLocaleLowerCase() === 'delete') {

        config.data = qs.stringify(config.data)
      }
      return config
    },
    error => {
      // 請求錯誤時做些事(接口錯誤、超時等)
      // Tip: 4
      // 關(guān)閉loadding
      console.log('request:', error) 
    
      // 1.判斷請求超時
      if (error.code === 'ECONNABORTED' && error.message.indexOf('timeout') !== -1) {
        console.log('根據(jù)你設(shè)置的timeout/真的請求超時 判斷請求現(xiàn)在超時了,你可以在這里加入超時的處理方案')
        // return service.request(originalRequest);//例如再重復(fù)請求一次
      }
      // 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) // 在調(diào)用的那邊可以拿到(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
      }
      // 根據(jù)返回的code值來做不同的處理(和后端約定)
      switch (data.code) {
        case '':
        break;
        default:
      }
      // 若不是正確的返回code,且已經(jīng)登錄,就拋出錯誤
      // 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 = '未授權(quán),請登錄'
          break
      
          case 403:
          err.message = '拒絕訪問'
          break
      
          case 404:
          err.message = `請求地址出錯: ${err.response.config.url}`
          break
      
          case 408:
          err.message = '請求超時'
          break
      
          case 500:
          err.message = '服務(wù)器內(nèi)部錯誤'
          break
      
          case 501:
          err.message = '服務(wù)未實現(xiàn)'
          break
      
          case 502:
          err.message = '網(wǎng)關(guān)錯誤'
          break
      
          case 503:
          err.message = '服務(wù)不可用'
          break
      
          case 504:
          err.message = '網(wǎng)關(guān)超時'
          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

/* 將所有接口統(tǒng)一起來便于維護
 * 如果項目很大可以將 url 獨立成文件,接口分成不同的模塊
 * 此處的數(shù)據(jù)依然來自 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 原型上調(diào)用 $api 了

總結(jié)

  1. 以上二次封裝較為全面,基本完成了我們之前的需求
  2. 在錯誤的處理上還需要與后端協(xié)定好返回值,做具體的約定
  3. 封裝回調(diào)有點多,在使用的時候也需要加上 then() 來處理結(jié)果,async & await 了解一下喲,好東西當然要藏起來,我才不會分享出來呢...

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

import 'babel-polyfill'

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 一步步帶你用vite簡單搭建ts+vue3全家桶

    一步步帶你用vite簡單搭建ts+vue3全家桶

    Vue3與TS的聯(lián)合是大趨勢,下面這篇文章主要給大家介紹了關(guān)于用vite簡單搭建ts+vue3全家桶的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-07-07
  • 簡單實現(xiàn)vue驗證碼60秒倒計時功能

    簡單實現(xiàn)vue驗證碼60秒倒計時功能

    這篇文章主要為大家介紹了如何簡單實現(xiàn)vue驗證碼60秒倒計時功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • ant design Vue 純前端實現(xiàn)分頁問題

    ant design Vue 純前端實現(xiàn)分頁問題

    這篇文章主要介紹了ant design Vue 純前端實現(xiàn)分頁問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • Vue父子組件傳值的一些坑

    Vue父子組件傳值的一些坑

    這篇文章主要介紹了Vue父子組件傳值的一些坑,幫助大家更好的理解和使用vue父子組件,感興趣的朋友可以了解下
    2020-09-09
  • vue實現(xiàn)錨點跳轉(zhuǎn)之scrollIntoView()方法詳解

    vue實現(xiàn)錨點跳轉(zhuǎn)之scrollIntoView()方法詳解

    這篇文章主要介紹了vue實現(xiàn)錨點跳轉(zhuǎn)之scrollIntoView()方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • vue解決子組件樣式覆蓋問題scoped deep

    vue解決子組件樣式覆蓋問題scoped deep

    文章主要介紹了在Vue項目中處理全局樣式和局部樣式的方法,包括使用scoped屬性和深度選擇器(/deep/)來覆蓋子組件的樣式,作者建議所有組件必須使用scoped,以避免樣式?jīng)_突,對于父組件覆蓋子組件的樣式,作者推薦給子組件指定自定義類名
    2025-01-01
  • vue-treeselect顯示unknown的問題及解決

    vue-treeselect顯示unknown的問題及解決

    這篇文章主要介紹了vue-treeselect顯示unknown的問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • VUE2實現(xiàn)事件驅(qū)動彈窗示例

    VUE2實現(xiàn)事件驅(qū)動彈窗示例

    本篇文章主要介紹了VUE2實現(xiàn)事件驅(qū)動彈窗示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • vue2.0 + ele的循環(huán)表單及驗證字段方法

    vue2.0 + ele的循環(huán)表單及驗證字段方法

    今天小編就為大家分享一篇vue2.0 + ele的循環(huán)表單及驗證字段方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09
  • vue+element實現(xiàn)批量刪除功能的示例

    vue+element實現(xiàn)批量刪除功能的示例

    下面小編就為大家分享一篇vue+element實現(xiàn)批量刪除功能的示例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-02-02

最新評論

茶陵县| 开原市| 罗山县| 蒲江县| 卓尼县| 哈尔滨市| 扎赉特旗| 梁山县| 历史| 房产| 房山区| 洱源县| 抚松县| 靖边县| 牟定县| 永川市| 宜宾市| 丹凤县| 扎囊县| 日喀则市| 宿迁市| 中卫市| 邳州市| 个旧市| 古田县| 上饶市| 京山县| 盖州市| 四子王旗| 师宗县| 湘潭县| 井研县| 新疆| 沐川县| 清远市| 南川市| 鹤庆县| 扶绥县| 尼木县| 肃北| 竹北市|