vue - axios封装

1.安装axios
npm i axios
环境配置.png

.env.development.png

.env.production.png

.env.test.png

package.json.png
2.新建一个axios.js文件,对axios进行封装
import axios from 'axios'
import QS from 'qs' // 引入qs模块,用来序列化post类型的数据
import jsonBig from 'json-bigint' // 解决后端返回大数字问题(控制台中preview和response值不同)
import store from '@/store/index' // 导入vuex,因为我们要使用到里面的状态对象
import { Message, Loading } from 'element-ui'; 

// 请求加载
let loading:any
let needLoadingRequestCount = 0
function showLoading () {
    if(needLoadingRequestCount === 0) {
        loading = Loading.service({
            lock: true,
            text: '加载中...',
            background: 'rgba(0,0,0,0.2)'
        })
    }
}
function hideLoading () {    
    if(needLoadingRequestCount <= 0) return
    needLoadingRequestCount--
    if(needLoadingRequestCount === 0) {
        loading.close()
    }
}

// axios基本配置信息:baseURL、设置请求超时、请求头设置
const instance = axios.create({
  baseURL: process.env.VUE_APP_DATA_URL,
  timeout: 10000,  // 若为0表示无超时时间
  headers: {
      'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
  },
  // `transformResponse` 在传递给 then/catch 前,允许修改响应数据
  transformResponse: [function (data) {
        try {
            // 如果转换成功则返回转换的数据结果
            return jsonBig.parse(data)
        } catch (err) {
            // 如果转换失败,则包装为统一数据格式并返回
            return {
                data
            }
        }
    }]
})

// 携带当前页面路径跳转登录页,登录完成后返回当前页面
const toLogin = () => {
    router.replace({
        path:'/login',
        query:{
            redirect:router.currentRoute.fullPath
        }
    })
}

// 提示函数
const tip = msg => {
    Message({
        icon: 'warning',
        message:msg
    })
}

// 请求拦截
instance.interceptors.request.use(
    config => {
        /*
            每次发送请求之前判断vuex中是否存在token
            若存在,统一在http请求的header上都加上token,后台根据token判断你的登录情况
            即使本地存在token也有可能是过期的
            所以在响应拦截器中对返回状态进行判断
            token
                一般登录完成,将用户的token通过localstorage或cookie存在本地
                用户在每次进入页面的时候,先从本地存储中读取token
                若token存在则说明用户已经登录过,更新vuex中的token状态
                每次请求接口的时候,请求头中携带token,后台判断携带的token是否过期
                若未携带,则说明没有登录过
        */
        showLoading()
        const token = store.state.token
        token && (config.headers.Authorization = token)
        return config
    },
    error => {
        hideLoading()
        return Promise.error(error)
    }
)

// 响应拦截:服务器返回给我们的数据,进行统一的处理
instance.interceptors.response.use(
    response => {
        hideLoading()
        if(response.status === 200){
            return Promise.resolve(response)
        } else {
            return Promise.reject(response)
        }
    },
    /*
        以下是服务器状态码不是2开头的情况,和后台人员协商好统一的错误状态码
    */
    error => {
        hideLoading()
        if (error.response.status) {
            switch (error.response.status){
                // 401未登录,携带当前页面路径跳转至登录页面,登录成功跳转至当前页
                case 401:
                    toLogin()
                    break;         
                // 403 token过期,对用户进行过期提示,清除本地token和vuex的token对象,跳转至登录页
                case 403:
                    tip('登录过期,请重新登录')
                    localStorage.removeItem('token');
                    store.commit('loginSuccess', null);
                    setTimeout(() => {                        
                        toLogin()                   
                    }, 1000);                    
                    break; 
                // 404请求不存在
                case 404:
                    tip('网络请求不存在')
                    break;
                // 其他错误,直接抛出错误提示
                default:
                    tip(error.response.data.message)
            }
            return Promise.reject(error.response)
        }
    }    
)

// get方法的封装(url-请求的地址,params-请求的参数)
export function get(url,params){
    return new Promise((resolve,reject)=>{
        instance.get(url,{
            params:params
        }).then(res => {
            resolve(res.data)
        }).catch(err => {
            reject(err.data)
        })
    })
}

// post方法的封装(url-请求的地址,params-请求的参数)
export function post(url,params){
    return new Promise((resolve,reject)=>{
        instance.post(url,QS.stringify(params)).then(res => {
            resolve(res.data)
        }).catch(err => {
            reject(err.data)
        })
    })
}
3.api.js(api的统一管理,模块化)
// address.js
import { get, post } from './axios.js'
const address = {
    // 如一个post请求的接口,url: http://www.baiodu.com/api/v1/users/my_address/address_edit_before
    apiAddress(p){
        return post('api/v1/users/my_address/address_edit_before', p)
    },
    apiAddressDetail(p){
        return post('api/v1/users/my_address/address_detail', p)
    }
}
export default address



// index.js
import address from 'api/address.js'
import article from 'api/article.js'
...// 其它模块的接口

export default {
    address,
    article
}



// main.js
import Vue from 'vue'
import App from './App'
import router from './router' // 导入路由文件
import store from './store' // 导入vuex文件
import api from './api/index' // 导入api接口

Vue.prototype.$api = api    // api挂载到vue原型上
4.封装好的接口调用
export default{
    name:'',
    created(){
        this.onLoad()    
    },
    methods:{
        onLoad(){
            this.$api.address.apiAddress({
                type:0,sort:1
            }).then(
                res=>{
                    // 获取数据成功的其它操作
                }
            )
        }
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,084评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,623评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,450评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,322评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,370评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,274评论 1 300
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,126评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,980评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,414评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,599评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,773评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,470评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,080评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,713评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,852评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,865评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,689评论 2 354

推荐阅读更多精彩内容