vue项目之axios的封装

267 阅读4分钟

不重要的前言

入前端很多年了,习惯把工作中遇到的问题、值得学习的技术及方法记录在QQ日志里。(hahaha~,我猜很多人会说,啥年代了,居然还有这么low的人。)
因为从第一家公司开始用QQ交流比较多,工作中遇到的问题,如何解决的;或者看到好的技术,顺手记录在QQ日志很方便,也就渐渐习惯了。 我会慢慢将之前记录一些好的内容分享给大家,一起共勉。~

一、简述

通常在做项目的时候,我们会对某些模块进行封装,这不仅防止了代码的冗余,还能大大提高工作效率。下面步入正题:

为什么要封装axios?
  1. 简化method方法,少写代码
  2. http错误码及请求返回的code错误码可以集中处理
  3. 某些接口需要携带登录后的token

下面就先来讲一下如何 “ 简化method方法 ”,如果不太明白,请耐心往下读~~~

二、axios封装

1. get、post、delet、put方法封装及使用

  1. 封装: 首先我在项目的 /src/util 文件下创建了request.js,封装了axios常用的method方法
const Axios = axios.create({
 baseURL: process.env.VUE_APP_BASE_API,
 timeout: 30000,
})
const baseUrl = function(url, method, config) {
  const configs = {
    method,
    url,
    headers: {}
  }
  if (config) {
    if (method === 'get' || method === 'delet') {
      configs.params = config
    } else {
      configs.data = config
    }
  }
  return new Promise((resolve, reject) => {
    Axios(configs)
      .then((res) => {
        resolve(res)
      })
      .catch((error) => {
        console.log('-------封装axios 的错误:', error.request)
        reject(error)
      })
  })
}
/**
 * ! 封装aixos 中get、post、put、delet方法
 */
const method = ['get', 'post', 'put', 'delet']
const request = method.reduce((total, current) => {
  total[current] = function(url, config) {
    return baseUrl(url, current, config)
  }
  return total
}, {})
// 抛出 request 对象
export default request
  1. 使用(顺带说一下怎么统一管理api请求): 整齐的api就像电路板一样,即使再复杂也能很清晰整个线路。新建一个indexApi.js,然后在这个文件中存放我们所有的api接口。 a. 在项目的 /src 目录下 新建了下图目录及文件; 在这里插入图片描述 b. indexAPi.js里引入了request.js文件里封装好的method方法

    我们定义了一个userInfoRequst方法,这个方法有一个参数config,config是我们请求接口时携带的参数对象。而后调用了我们封装的get方法,get方法的第一个参数是我们的接口地址,第二个参数是userInfoRequst 的config参数,即请求接口时携带的参数对象。最后通过export导出userInfoRequst 。

    代码如下(示例):

    import request from '../util/request'
    // 获取当前登录用户信息
    export const userInfoRequst = function(config) {
      return request.get('/user/access', config)
    }
    

    c. 然后页面中调用api接口

    代码如下(示例):

    import { userInfoRequst } from '@/api/Indexapi';// 导入我们的api接口
    export default {        
       name: 'UserInfo',    
       created () {
           this.onLoad();
       },
       methods: {            
           // 获取数据            
           onLoad() {
               // 调用api接口,并且提供了1个参数                
               userInfoRequst({                    
                   loginCode: '132131',                                   
               }).then(res => {
                   // 获取数据成功后的操作           
               }).catch((error)=>{
                  // 处理 Promise 的reject 抛出的错误异常
               })           
           }        
       }
    }
    

请求拦截、响应拦截

下面主要分享一下如何携带登录状态的token信息等以及如何集中管理请求返回的错误code。 本次的内容主要涉及到axios的请求拦截、响应拦截。

一、请求拦截

1. 什么是请求拦截呢?

请求拦截器的作用是在请求发送前进行一些操作,例如在每个请求体里加上token,统一做了处理如果以后要改也非常容易

2. 代码示例

下面呢,给大家放一下代码,可以一目了然。

import axios from "axios";
// 创建axios实例
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API,
  timeout: 30000,
});
// request请求拦截器
service.interceptors.request.use(
  config => {
  	// 在发送请求之前做些什么,例如加入token
    config.headers["token"] = "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ"; //请求头中添加token
    config.headers["userId"] = '131313';//可以添加项目需要的一些信息等等...
    return config;
  },
  error => {
    Promise.reject(error);
  }
);

二、响应拦截

1. 什么是响应拦截呢?

响应拦截器的作用是在接收到响应后进行一些操作,可以统一管理返回的状态码,最常见的例如在服务器返回登录状态失效,需要重新登录的时候,跳转到登录页。

代码如下(示例):

// 响应拦截器
axios.interceptors.response.use(    
    response => {        
    	// 在接收响应做些什么
        if (response.status === 200) {            
            return Promise.resolve(response);        
        } else {            
            return Promise.reject(response);        
        }    
    },
    // 服务器状态码不是200的情况    
    error => {        
        if (error.response.status) {            
            switch (error.response.status) {                
                // 401: 未登录                
                // 未登录则跳转登录页面,并携带当前页面的路径                
                // 在登录成功后返回当前页面,这一步需要在登录页操作。                
                case 401:                    
                    router.replace({                        
                        path: '/login',                        
                        query: { redirect: router.currentRoute.fullPath } 
                    });
                    break;
                // 403 token过期                        
                case 403:                             
                    break; 
                // 404请求不存在                
                case 404:                    
                    Toast({                        
                        message: '网络请求不存在',                        
                        duration: 1500,                        
                        forbidClick: true                    
                    });                    
                break;                
                // 其他错误,直接抛出错误提示                
                default:                    
                    Toast({                        
                        message: error.response.data.message,                        
                        duration: 1500,                        
                        forbidClick: true                    
                    });            
            }            
            return Promise.reject(error.response);        
        }       
    }
);

总结

以上就是今天要讲的内容,如果哪里不明白或者表达错误的地方,欢迎大家来指正,三克油啦~~~