axios/api 封裝及應(yīng)用

更新時間:2020-12-10

許多小伙伴在接觸了vue之后虐呻,肯定知道在vue項目開發(fā)過程中都會有一個配置文件掸掏,沒錯就是vue.config.js(vue-cli3+)船殉,在這個文件里可以配置很多東西,比如說接口代理炕桨、跨域之類的饭尝,所以很多剛接觸vue的小伙伴很難分清接口代理和api封裝。

簡單來說献宫,api封裝就是將接口統(tǒng)一管理钥平,但是要將接口統(tǒng)一管理,需要調(diào)用axiso的一些方法姊途,因此我們在開始api 之前要先將axiso進行封裝(將axiso的功能整合涉瘾,方便自己調(diào)用)

此外axiso封裝后,可以根據(jù)不同的環(huán)境捷兰,切換接口地址立叛,這一點非常實用。

廢話不多說贡茅,axiso封裝 → http.js

import axios from 'axios';
import QS from 'qs';

import router from './router'  // 配合路由守衛(wèi)秘蛇,進行攔截
import store from './store'    // 多用于token存取

/**
 環(huán)境的切換
*/
if (process.env.NODE_ENV === 'development') {   //開發(fā)環(huán)境
    axios.defaults.baseURL = '……'; //測試接口
} else if (process.env.NODE_ENV === 'test') {   //測試環(huán)境
    axios.defaults.baseURL = '……';  //測試接口
} else if (process.env.NODE_ENV === 'production') { //線上環(huán)境
    axios.defaults.baseURL = '……'; //測試接口
}

// 請求超時時間 10S
axios.defaults.timeout = 10000;

// 請求頭
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';

/**
 * http request 請求攔截,一般用于token 驗證
 */

axios.interceptors.request.use(
    config => {
        if(store.state.token){  // 判斷token 是否存在友扰,如果存在拼到請求地址后邊
            let reg = new RegExp('"',"g");    //刪除請求地址中的 "
            // 在請求地址中加上 token
            config.url = `${config.url}?token=${store.state.token}`.replace(reg,"");
        }
        return config;
    },
    error => {
        console.log('請求攔截器彤叉!');
        return Promise.reject(error);
    }
);

/**
 * http response 響應(yīng)攔截 
 */ 
axios.interceptors.response.use(
    /**
     * 如果返回的狀態(tài)碼為200,說明接口請求成功村怪,可以正常拿到數(shù)據(jù)
     * 否則的話拋出錯誤
     */ 
    response => {
        if (response.status === 200) {
            return Promise.resolve(response);
        } else {
            return Promise.reject(response);
        }
    },
    /**
     * 服務(wù)器狀態(tài)碼不是200的的情況
     * 這里可以跟你們的后臺開發(fā)人員協(xié)商好統(tǒng)一的錯誤狀態(tài)碼
     * 然后根據(jù)返回的狀態(tài)碼進行一些操作,例如登錄過期提示浮庐,錯誤提示等等
     * 下面列舉幾個常見的操作甚负,其他需求可自行擴展
     */
    error => {   
        if (error.response.status) {
            switch (error.response.status) {
                /**
                 * 401: 未登錄
                 * 未登錄則跳轉(zhuǎn)登錄頁面柬焕,并攜帶當前頁面的路徑 
                 * 在登錄成功后返回當前頁面,這一步需要在登錄頁操作梭域。 
                 */   
                case 401:
                    router.replace({
                        path: '/',
                        query: {
                            redirect: router.currentRoute.fullPath
                        }
                    });
                    break;
                /**
                 * 403 token過期 
                 * 登錄過期對用戶進行提示
                 * 清除本地token和清空vuex中token對象
                 * 跳轉(zhuǎn)登錄頁面
                 */ 
                case 403:
                    console.log('登錄過期斑举,請重新登錄');
                    // 清除token     
                    localStorage.removeItem('token');
                    store.commit('loginSuccess', null); // 不太懂的話可不對狀態(tài)碼進行操作
                    // 跳轉(zhuǎn)頁面,并將要瀏覽的頁面通過fullPath傳過去病涨,登錄成功后可跳轉(zhuǎn)至需要訪問的頁面
                    setTimeout(() => {
                        router.replace({
                            path: '/',
                            query: {
                                redirect: router.currentRoute.fullPath
                            }
                        });
                    }, 1000);
                    break;
                /**
                 * 404請求不存在 
                 */   
                case 404:
                    console.log('請求網(wǎng)絡(luò)請求不存在');
                    break; 
                /**
                 * 其他錯誤富玷,直接拋出錯誤提示
                 */   
                default:
                    console.log(error.response.data.message);
            }
            return Promise.reject(error.response);
        }
    }
);

/** 
 * get方法,對應(yīng)get請求 
 * @param {String} url [請求的url地址] 
 * @param {Object} params [請求時攜帶的參數(shù)] 
 */
export function get(url, params) {
    return new Promise((resolve, reject) => {
        axios.get(url, { params: params }) .then(res => {
            resolve(res.data);
        }).catch(err => {
            reject(err.data)
        })
    });
}
/** 
 * post方法既穆,對應(yīng)post請求 
 * @param {String} url [請求的url地址] 
 * @param {Object} params [請求時攜帶的參數(shù)] 
 * @param {String} type [參數(shù)類型赎懦,默認表單數(shù)據(jù),可能為json] 
 */
export function post(url, params) {
     if(type){  // 傳輸方式為json
        let headers = {'Content-Type': 'application/json;'};
        if(type == 'DATA' || type == 'data'){  // 有文件傳輸
            headers = {'Content-Type': 'multipart/form-data;'};
        }
        return new Promise((resolve, reject) => {
            axios({
                headers,
                method: 'POST',
                url,
                data:params
            }).then(res => {
                resolve(res.data);
            }).catch(err => {
                reject(err.data);
            });
        });
    }else{  // 傳輸方式為表單
        return new Promise((resolve, reject) => {
            axios.post(url, QS.stringify(params)).then(res => {
                resolve(res.data);
            }).catch(err => {
                reject(err.data);
            });
        }); 
    }
}

這是一個非常簡單的分裝幻工,可以簡單的使用post/get請求励两,axiso的封裝遠不止如此,比如響應(yīng)攔截囊颅、錯誤處理等当悔。
接下來接口管理 → api.js

//引入http.js
import { get, post } from './http.js'  

export const apiConfig = {
    // 編寫接口
    getTest:par => post('/test', par),  //這樣就寫好了一個接口,可以使用了
}

組件內(nèi)使用封裝后的接口

<script>
//引入api.js
import {apiConfig} from '../../../api/api'

export default {
    name:'testCom',
    methods:{
        // 獲取數(shù)據(jù)
        getData(par){
            apiConfig.getTest({'name':par}).then(res => {
                console.log(res);
            })
        }
    },
    mounted(){ 
        this.getData('小明')  //鉤子函數(shù)中調(diào)用方法獲取數(shù)據(jù)   
    },
}
</script>

PS:在實際的工作或?qū)W習(xí)中踢代,并不一定只有這一種方式盲憎,方法的編寫和調(diào)用也不要照抄照搬,在這里只是分享一個可行的思路胳挎,以至于其它的就要靠小伙伴自己研究了饼疙,此外,雖然此文以 vue 舉例說明串远,但是主要對于axios 的封裝宏多,并不僅限于此,例如在 react 項目中也同樣適用哦~

另外附贈目錄截圖澡罚,以免有的小伙伴不知道文件建在那里伸但,產(chǎn)生疑惑。


項目目錄
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末留搔,一起剝皮案震驚了整個濱河市更胖,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌隔显,老刑警劉巖却妨,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異括眠,居然都是意外死亡彪标,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門掷豺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來捞烟,“玉大人薄声,你說我怎么就攤上這事√饣” “怎么了默辨?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長苍息。 經(jīng)常有香客問我缩幸,道長,這世上最難降的妖魔是什么竞思? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任表谊,我火速辦了婚禮,結(jié)果婚禮上衙四,老公的妹妹穿的比我還像新娘铃肯。我一直安慰自己,他們只是感情好传蹈,可當我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布押逼。 她就那樣靜靜地躺著,像睡著了一般惦界。 火紅的嫁衣襯著肌膚如雪挑格。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天沾歪,我揣著相機與錄音漂彤,去河邊找鬼。 笑死灾搏,一個胖子當著我的面吹牛挫望,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播狂窑,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼媳板,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了泉哈?” 一聲冷哼從身側(cè)響起蛉幸,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎丛晦,沒想到半個月后奕纫,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡烫沙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年匹层,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片锌蓄。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡又固,死狀恐怖仲器,靈堂內(nèi)的尸體忽然破棺而出煤率,到底是詐尸還是另有隱情仰冠,我是刑警寧澤,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布蝶糯,位于F島的核電站洋只,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏昼捍。R本人自食惡果不足惜识虚,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望妒茬。 院中可真熱鬧担锤,春花似錦、人聲如沸乍钻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽银择。三九已至多糠,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間浩考,已是汗流浹背夹孔。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留析孽,地道東北人搭伤。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像袜瞬,于是被迫代替她去往敵國和親怜俐。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,614評論 2 353

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