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

更新時間:2025-7-16

最新使用方案:ez-axios

許多小伙伴在接觸了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)登錄頁面,并攜帶當(dāng)前頁面的路徑 
                 * 在登錄成功后返回當(dāng)前頁面,這一步需要在登錄頁操作。 
                 */   
                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ù)類型,默認(rèn)表單數(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的封裝遠(yuǎn)不止如此,比如響應(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)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容