vue.cli項(xiàng)目封裝全局axios缝驳,封裝請(qǐng)求连锯,封裝公共的api和調(diào)用請(qǐng)求的全過(guò)程

前言

在做vue中大型項(xiàng)目的時(shí)候,官方推薦使用axios用狱,但是原生的axios可能對(duì)項(xiàng)目的適配不友好运怖,所以,在工程開始的來(lái)封裝一下axios夏伊,保持全項(xiàng)目數(shù)據(jù)處理的統(tǒng)一性摇展。此文主要講在vue-cil項(xiàng)目中如何封裝axios,封裝請(qǐng)求溺忧,封裝公共的api咏连,頁(yè)面如何調(diào)用請(qǐng)求。

如果你能看到這篇文章鲁森,鑒于有很多小白可能會(huì)參考我這篇文章來(lái)進(jìn)行前期配置祟滴,特說(shuō)明下正式配置路線:
1.拿到項(xiàng)目及后臺(tái)接口,首先做的是配置全局代理及第二點(diǎn)歌溉;
2. 全局封裝axios及第三點(diǎn)request.js垄懂;
3.過(guò)濾axios請(qǐng)求方式,控制路徑及參數(shù)的格式及第四點(diǎn)http.js;
4.正式封裝api及第五點(diǎn)api.js埠偿;
5.頁(yè)面調(diào)用;

正文

一榜晦、vue項(xiàng)目的前期配置

新建vue項(xiàng)目冠蒋,下載axios,并在main.js中導(dǎo)入axios

 npm i axios -S
//main.js
import axios from "axios";

二乾胶、配置config文件中的代理地址

在項(xiàng)目config目錄下的修改 index.js文件抖剿,這里是主要書寫配置多個(gè)后臺(tái)接口。關(guān)于代理可能出現(xiàn)的問(wèn)題识窿,可以查看我的另一篇文檔VueCil代理本地proxytable報(bào)錯(cuò)的解析斩郎;

vue cil2舊版本的代理配置——config/index.js

 dev: {
    // Paths
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    // 后端請(qǐng)求地址代理,配置后testIp再之后的頁(yè)面調(diào)用時(shí)就直接指代 http://197.82.15.15:8088
    proxyTable: {
      '/testIp': {
        target: 'http://197.82.15.15:8088',
        changeOrigin: true,
        pathRewrite: { 
          '^/testIp': ''
        }
      },
      '/elseIp': {
        target: 'http://182.83.19.15:8080',
        changeOrigin: true,
        pathRewrite: { 
          '^/esleIp': ''
        }
      },
    },

    // Various Dev Server settings
    host: 'localhost', // can be overwritten by process.env.HOST
    port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
    autoOpenBrowser: false,
    errorOverlay: true,
    notifyOnErrors: true,
    poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-


    /**
     * Source Maps
     */

    // https://webpack.js.org/configuration/devtool/#development
    devtool: 'cheap-module-eval-source-map',

    // If you have problems debugging vue-files in devtools,
    // set this to false - it *may* help
    // https://vue-loader.vuejs.org/en/options.html#cachebusting
    cacheBusting: true,

    cssSourceMap: true
  },

vuecil 3+ 新版本的代理配置–vue.config.js 文件

關(guān)于多代理配置:

         devServer: {
            overlay: { // 讓瀏覽器 overlay 同時(shí)顯示警告和錯(cuò)誤
              warnings: true,
              errors: true
            },
            host: "localhost",
            port: 8080, // 端口號(hào)
            https: false, // https:{type:Boolean}
            open: false, //配置后自動(dòng)啟動(dòng)瀏覽器
            hotOnly: true, // 熱更新
            // proxy: 'http://localhost:8080'   // 配置跨域處理,只有一個(gè)代理
            proxy: { //配置多個(gè)代理
                "/testIp": {
                    target: "http://197.0.0.1:8088",
                    changeOrigin: true,
                    ws: true,//websocket支持
                    secure: false,
                    pathRewrite: {
                        "^/testIp": "/"
                    }
                },
                "/elseIp": {
                    target: "http://197.0.0.2:8088",
                    changeOrigin: true,
                    //ws: true,//websocket支持
                    secure: false,
                    pathRewrite: {
                        "^/elseIp": "/"
                    }
                },
            }
        }

如果有多后臺(tái)喻频,就可以在api文件夾下另外新建一個(gè)elseApi.js 缩宜,書寫當(dāng)前ip下的接口請(qǐng)求。方法同上甥温,只是 let resquest = "/elseIp/request/" 調(diào)用的時(shí)候把端口更改一下锻煌。

三、封裝axios實(shí)例 —— request.js

在項(xiàng)目src目錄下新建utils文件夾姻蚓,然后在其中新建 request.js文件宋梧,這個(gè)文件是主要書寫axios的封裝過(guò)程。

/****   request.js   ****/
// 導(dǎo)入axios
import axios from 'axios'
// 使用element-ui Message做消息提醒
import { Message} from 'element-ui';
//1. 創(chuàng)建新的axios實(shí)例狰挡,
const service = axios.create({
  // 公共接口--這里注意后面會(huì)講
  baseURL: process.env.BASE_API,
  // 超時(shí)時(shí)間 單位是ms捂龄,這里設(shè)置了3s的超時(shí)時(shí)間
  timeout: 3 * 1000
})
// 2.請(qǐng)求攔截器
service.interceptors.request.use(config => {
  //發(fā)請(qǐng)求前做的一些處理,數(shù)據(jù)轉(zhuǎn)化加叁,配置請(qǐng)求頭倦沧,設(shè)置token,設(shè)置loading等,根據(jù)需求去添加
   config.data = JSON.stringify(config.data); //數(shù)據(jù)轉(zhuǎn)化,也可以使用qs轉(zhuǎn)換
   config.headers = {
     'Content-Type':'application/x-www-form-urlencoded' //配置請(qǐng)求頭
   }
   //注意使用token的時(shí)候需要引入cookie方法或者用本地localStorage等方法它匕,推薦js-cookie
   const token = getCookie('名稱');//這里取token之前刀脏,你肯定需要先拿到token,存一下
   if(token){
      config.params = {'token':token} //如果要求攜帶在參數(shù)中
      config.headers.token= token; //如果要求攜帶在請(qǐng)求頭中
    }
  return config
}, error => {
  Promise.reject(error)
})

// 3.響應(yīng)攔截器
service.interceptors.response.use(response => {
  //接收到響應(yīng)數(shù)據(jù)并成功后的一些共有的處理,關(guān)閉loading等
  
  return response
}, error => {
   /***** 接收到異常響應(yīng)的處理開始 *****/
  if (error && error.response) {
    // 1.公共錯(cuò)誤處理
    // 2.根據(jù)響應(yīng)碼具體處理
    switch (error.response.status) {
      case 400:
        error.message = '錯(cuò)誤請(qǐng)求'
        break;
      case 401:
        error.message = '未授權(quán)超凳,請(qǐng)重新登錄'
        break;
      case 403:
        error.message = '拒絕訪問(wèn)'
        break;
      case 404:
        error.message = '請(qǐng)求錯(cuò)誤,未找到該資源'
        window.location.href = "/NotFound"
        break;
      case 405:
        error.message = '請(qǐng)求方法未允許'
        break;
      case 408:
        error.message = '請(qǐng)求超時(shí)'
        break;
      case 500:
        error.message = '服務(wù)器端出錯(cuò)'
        break;
      case 501:
        error.message = '網(wǎng)絡(luò)未實(shí)現(xiàn)'
        break;
      case 502:
        error.message = '網(wǎng)絡(luò)錯(cuò)誤'
        break;
      case 503:
        error.message = '服務(wù)不可用'
        break;
      case 504:
        error.message = '網(wǎng)絡(luò)超時(shí)'
        break;
      case 505:
        error.message = 'http版本不支持該請(qǐng)求'
        break;
      default:
        error.message = `連接錯(cuò)誤${error.response.status}`
    }
  } else {
    // 超時(shí)處理
    if (JSON.stringify(error).includes('timeout')) {
      Message.error('服務(wù)器響應(yīng)超時(shí)愈污,請(qǐng)刷新當(dāng)前頁(yè)')
    }
    error.message = '連接服務(wù)器失敗'
  }

  Message.error(error.message)
  /***** 處理結(jié)束 *****/
  //如果不需要錯(cuò)誤處理,以上的處理過(guò)程都可省略
  return Promise.resolve(error.response)
})
//4.導(dǎo)入文件
export default service

特殊說(shuō)明:

鑒于有很多朋友問(wèn)關(guān)于數(shù)據(jù)轉(zhuǎn)換這塊的問(wèn)題轮傍,特在頁(yè)面中單獨(dú)回復(fù)一下暂雹!

config.data = JSON.stringify(config.data);
config.headers = { 'Content-Type':'application/x-www-form-urlencoded'  }
const token = getCookie('名稱')
if(token){ 
  config.params = {'token':token} ; 
  config.headers.token= token; 
}

上述的代碼都是請(qǐng)求的配置項(xiàng),非必須创夜,也是分情況的杭跪,data/headers /params 這種本身的參數(shù)都有多種,和后臺(tái)溝通,需要什么就配什么涧尿!
config.data = JSON.stringify(config.data);為什么不用qs.stringify系奉,因?yàn)槲业暮笈_(tái)想要的只是json類型的傳參,而qs轉(zhuǎn)換會(huì)轉(zhuǎn)換成為鍵值對(duì)拼接的字符串形式姑廉。當(dāng)然你們后臺(tái)需要傳遞字符串類型參數(shù)缺亮,那就換成qs或者其他格式方式。
const token = getCookie('名稱')這是token的取值桥言,在取之前你肯定需要發(fā)請(qǐng)求拿到token萌踱,然后setCookie存起來(lái),而名稱就是你存的token的名稱号阿,每個(gè)人的不一樣并鸵;
config.headers = { 'Content-Type':'application/x-www-form-urlencoded' }請(qǐng)求頭內(nèi)容的配置,也是不同的扔涧,application/x-www-form-urlencoded :form表單數(shù)據(jù)被編碼為key/value格式發(fā)送到服務(wù)器(表單默認(rèn)的提交數(shù)據(jù)的格式)园担,你可以根據(jù)實(shí)際情況去配置自己需要的;
以上
我已經(jīng)舉了很清晰的例子枯夜,寫代碼的過(guò)程是自己動(dòng)腦去搭建工程的粉铐,希望能看到我文章的各位,善于搜索卤档,善于思考蝙泼,善于總結(jié);
當(dāng)然我很喜歡幫大家解決問(wèn)題劝枣,但是相關(guān)的基礎(chǔ)問(wèn)題汤踏,還是建議自己去學(xué)習(xí)掌握。

四舔腾、封裝請(qǐng)求——http.js

在項(xiàng)目src目錄下的utils文件夾中新建 http.js文件溪胶,這個(gè)文件是主要書寫幾種請(qǐng)求的封裝過(guò)程。

/****   http.js   ****/
// 導(dǎo)入封裝好的axios實(shí)例
import request from './request'

const http ={
    /**
     * methods: 請(qǐng)求
     * @param url 請(qǐng)求地址 
     * @param params 請(qǐng)求參數(shù)
     */
    get(url,params){
        const config = {
            method: 'get',
            url:url
        }
        if(params) config.params = params
        return request(config)
    },
    post(url,params){
        const config = {
            method: 'post',
            url:url
        }
        if(params) config.data = params
        return request(config)
    },
    put(url,params){
        const config = {
            method: 'put',
            url:url
        }
        if(params) config.params = params
        return request(config)
    },
    delete(url,params){
        const config = {
            method: 'delete',
            url:url
        }
        if(params) config.params = params
        return request(config)
    }
}
//導(dǎo)出
export default http

五稳诚、正式封裝API哗脖,用于發(fā)送請(qǐng)求——api.js

在項(xiàng)目src目錄下新建api文件夾,然后在其中新建 api.js文件扳还,這個(gè)文件是主要書寫API的封裝過(guò)程才避。

寫法一:適合分類導(dǎo)出

import http from '../utils/http'
// 
/**
 *  @parms resquest 請(qǐng)求地址 例如:http://197.82.15.15:8088/request/...
 *  @param '/testIp'代表vue-cil中config,index.js中配置的代理
 */
let resquest = "/testIp/request/"

// get請(qǐng)求
export function getListAPI(params){
    return http.get(`${resquest}/getList.json`,params)
}
// post請(qǐng)求
export function postFormAPI(params){
    return http.post(`${resquest}/postForm.json`,params)
}
// put 請(qǐng)求
export function putSomeAPI(params){
    return http.put(`${resquest}/putSome.json`,params)
}
// delete 請(qǐng)求
export function deleteListAPI(params){
    return http.delete(`${resquest}/deleteList.json`,params)
}


寫法二:使用全部導(dǎo)出

import http from '../utils/http'
// 
/**
 *  @parms resquest 請(qǐng)求地址 例如:http://197.82.15.15:8088/request/...
 *  @param '/testIp'代表vue-cil中config氨距,index.js中配置的代理
 */
let resquest = "/testIp/request/"

// get請(qǐng)求
export default{
    getListAPI(params){
        return http.get(`${resquest}/getList.json`,params)
    },
     postFormAPI(params){
        return http.post(`${resquest}/postForm.json`,params)
    }
}

注意:一個(gè)項(xiàng)目中如果后臺(tái)請(qǐng)求不是同一個(gè)ip桑逝,而是多個(gè)ip的時(shí)候,可以在api文件夾下建立多個(gè)js俏让,用來(lái)調(diào)用請(qǐng)求楞遏。
我們看下之前遺留的一個(gè)問(wèn)題:

//創(chuàng)建新的axios實(shí)例茬暇,
const service = axios.create({
  baseURL: process.env.BASE_API,
  timeout: 3 * 1000
})

在之前封裝公共接口的baseUrl時(shí)候,用了webpack中的全局變量process.env.BASE_API寡喝,而不是直接寫死ip糙俗,也是為了適應(yīng)多個(gè)后臺(tái)或者開發(fā)的時(shí)候的api地址和發(fā)布的時(shí)候的api地址不一樣這種情況。

以上 關(guān)于配置環(huán)境 和接口 基本搭建完畢预鬓,下面看一下調(diào)用:

六巧骚、如何在vue文件中調(diào)用

方法一:用到哪個(gè)api 就調(diào)用哪個(gè)接口——適用于上文接口分類導(dǎo)出;

 import {getListAPI,postFormAPI, putSomeAPI, deleteListAPI} from '@/api/api'

  methods: {
      //promise調(diào)用珊皿,鏈?zhǔn)秸{(diào)用, getList()括號(hào)內(nèi)只接受參數(shù)巨税;
      //   get不傳參
      getList() {
        getListAPI().then(res => console.log(res)).catch(err => console.log(err))
      },
        //post傳參
      postForm(formData) {
        let data = formData
        postFormAPI(data).then(res => console.log(res)).catch(err => console.log(err))
      },

      //async await同步調(diào)用
      async postForm(formData) {
        const postRes = await postFormAPI(formData)
        const putRes = await putSomeAPI({data: 'putTest'})
        const deleteRes = await deleteListAPI(formData.name)
        // 數(shù)據(jù)處理
        console.log(postRes);
        console.log(putRes);
        console.log(deleteRes);
      },
   }

方法二 :把a(bǔ)pi全部導(dǎo)入蟋定,然后用哪個(gè)調(diào)用哪個(gè)api——適用于全部導(dǎo)出

   import api from '@/api/api'
   methods: {
     getList() {
        api.getListAPI(data).then(res => {
          //數(shù)據(jù)處理
        }).catch(err => console.log(err))
      }
    }  

結(jié)語(yǔ)

以上就詳細(xì)介紹了,在vue-cil項(xiàng)目中 如何封裝axios草添,封裝請(qǐng)求驶兜,封裝公共的api,配置多個(gè)接口远寸,頁(yè)面如何調(diào)用請(qǐng)求等問(wèn)題抄淑,都是親測(cè)有用的~ 但是這種封裝方法的話,更適合大中型項(xiàng)目驰后,配置比較合理肆资,如果是自己小項(xiàng)目,就直接用axios就完事了灶芝。郑原。。

補(bǔ)充:
  • 關(guān)于代理的配置及若出現(xiàn)配置代理報(bào)錯(cuò)404的問(wèn)題夜涕,可以參考我的文章:代理的配置來(lái)解決犯犁;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市女器,隨后出現(xiàn)的幾起案子酸役,更是在濱河造成了極大的恐慌,老刑警劉巖驾胆,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件涣澡,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡丧诺,警方通過(guò)查閱死者的電腦和手機(jī)暑塑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)锅必,“玉大人事格,你說(shuō)我怎么就攤上這事惕艳。” “怎么了驹愚?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵远搪,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我逢捺,道長(zhǎng)谁鳍,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任劫瞳,我火速辦了婚禮倘潜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘志于。我一直安慰自己涮因,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布伺绽。 她就那樣靜靜地躺著养泡,像睡著了一般。 火紅的嫁衣襯著肌膚如雪奈应。 梳的紋絲不亂的頭發(fā)上澜掩,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音杖挣,去河邊找鬼肩榕。 笑死,一個(gè)胖子當(dāng)著我的面吹牛惩妇,可吹牛的內(nèi)容都是我干的点把。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼屿附,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼郎逃!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起挺份,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤褒翰,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后匀泊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體优训,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年各聘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了揣非。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡躲因,死狀恐怖早敬,靈堂內(nèi)的尸體忽然破棺而出忌傻,到底是詐尸還是另有隱情,我是刑警寧澤搞监,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布水孩,位于F島的核電站,受9級(jí)特大地震影響琐驴,放射性物質(zhì)發(fā)生泄漏俘种。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一绝淡、第九天 我趴在偏房一處隱蔽的房頂上張望宙刘。 院中可真熱鬧,春花似錦牢酵、人聲如沸悬包。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)玉罐。三九已至屈嗤,卻和暖如春潘拨,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背饶号。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工铁追, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人茫船。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓琅束,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親算谈。 傳聞我的和親對(duì)象是個(gè)殘疾皇子涩禀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容