vue项目中axios的封装

承接另一篇文章 vue-cli4 项目框架的搭建 以及 路由的封装、axios的封装、公共函数js文件的封装引用、vuex的基本用法、minins混入、css以及字体图标和图片的引入等 

这篇文章主要介绍对于 axios 的封装。代码结构如图:

主要改动的文件是图片中标红框的部分。

其中 axios.js 的代码为:

/**
 * 此文件主要创建 axios 实例,然后添加请求拦截器和响应拦截器
 */
import axios from 'axios'
import { Message } from 'element-ui';

//请求的服务器的地址
const basePath = 'http://10.10.15.210:28080'; 

//创建 axios 实例
const axiosInstance = axios.create({
  baseURL: basePath,
  withCredentials: true,  //是否允许跨域
  timeout: 9000
});

//添加请求拦截器
axiosInstance.interceptors.request.use(
  config => {
    // 在发送请求之前做些什么(可以在这里给头部添加token)
    // console.log("axios请求拦截器的config:",config);
    // if(sessionStorage.getItem("token")){
    //   config.headers.access_token = sessionStorage.getItem("token")
    // }
    return config;
  },
  error => {
    // 对请求错误做些什么
    console.log(error)
    return Promise.reject(error);
  }
);

//添加响应拦截器
axiosInstance.interceptors.response.use(
  response => {
    console.log("axios响应拦截器的数据:",response);
    /**
     * 对响应数据判断:
     *  如果成功返回数据,就通过return把数据返出去
     *  如果请求不成功,就在拦截器这里统一处理(组件的代码就不用关注错误的情况了)
     */
    if(response.status==200){
      return response.data;
      // return response;
      // return 123;
    }else{
      handleErrorData(response.data);
    }
    return response;
  },
  error => {
    // 对响应错误做点什么
    // console.log("axios响应拦截器的错误数据:",error);
    // Message.error(error.message);
    return Promise.reject(error);
  }
);
//对错误信息的处理函数
function handleErrorData(errMes){
  if(errMes.message){
    Message.error(errMes.message);
  }else{
    switch(errMes.code){
      case 401 :
        Message.error("未授权,请重新登录!");
        break;
      case 403 :
        Message.error("拒绝访问");
        break;
      case 404 :
        Message.error("很抱歉,资源未找到!");
        break;
      case 500 :
        Message.error("服务器错误!");
        break;
      case 504 :
        Message.error("网络超时!");
        break;
      default :
        Message.error("服务正在联调中,请稍后!");
        break;
    }
  }
}

export {axiosInstance}

 代码解析:

  1. 服务器地址的定义 basePath 的值依自己的项目而定,这里的 http://10.10.15.210:28080 只是示例。
  2. 首先创建 axios 实例,然后在 axios 实例上添加请求拦截器 和 响应拦截器。
  3. 请求拦截器的成功函数里面我们一般的用途都是给请求头部添加 token。
  4. 响应拦截器请求成功函数里的判断条件 response.status==200 依自己的项目中后端返回的数据而定,如果成功,则 return response.data ,这里返回的 response.data 就是我们项目中每个 .vue 文件中请求接口的返回值,在这里做了统一的封装,如果把 return response.data 改为 return 123 ,那么项目中所有的 .vue 文件中跟后端交互的数据返回的都是统一的数值 123
  5. 响应拦截器请求成功函数里面的的判断条件 response.status==200 如果不成立,则通过函数 handleErrorData 对错误消息统一处理,这样我们在项目中每个 .vue 文件中所有跟后端交互的时候,我们只关注请求成功时的数据处理即可,不用理会请求错误时的处理逻辑,因为在此处的响应拦截器里面统一处理了。至于 函数 handleErrorData 中的判断条件等等,依据自己的项目实际情况而定,可对应修改代码。
  6. 最后返回创建的 axios 实例 axiosInstance

注意:axios.js 中的 import { Message } from 'element-ui' ,项目中,以 .vue 结尾的文件,我们可以直接用 this.$message.error("错误消息") 的语法,是因为我们用框架elementui的时候,在 main.js 中定义的有,vue文件中的 this 指的是vue对象。而 js 文件中我们就不能用 this.$message.error("错误消息") 的语法,因为在js文件中,this 指的是 window 对象,所以我们需要通过 import { Message } from 'element-ui' 语法引入。 

其中 request.js 中的代码为:

/**
 * 此文件主要封装 axios 的get、post、delete等方法
 * (后续还可以添加文件的上传、下载、文件的导出等等)
 */

import { axiosInstance as axios } from "./axios.js"

//get
export function axiosGet(url,parameter={}) {
  return axios({  //这里的 axios 就是从 axios.js 中引入的 axiosInstance
    url: url,
    method: 'get',
    params: parameter
  })
}
//post
export function axiosPost(url,parameter={}) {
  return axios({
    url: url,
    method:'post' ,
    data: parameter
  })
}
//delete
export function axiosDelete(url,parameter={}) {
  return axios({
    url: url,
    method: 'delete',
    params: parameter
  })
}

代码解析:

  1.  从 axios.js 中引入 axios 的实例 axiosInstance,将其重命名为 axios
  2. 通过 axios API 定义get、post、delete 等方法,具体用法参见 axios 官网 API用法 
  3. 后续我们也可以在这个文件中拓展其他与服务器交互的方法,如文件的上传、下载、导出等等。

 其中 main.js 中的代码:

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

//elementui
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI, {size: 'small'});

//请求方法
import {axiosGet,axiosPost,axiosDelete} from "@/serversApi/request.js"
Vue.prototype.$axiosGet = axiosGet;
Vue.prototype.$axiosPost = axiosPost;
Vue.prototype.$axiosDelete = axiosDelete;

Vue.config.productionTip = false

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

代码解析:我们把请求方法定义到 vue 的原型 prototype 上,这样我们在项目中的 .vue 文件中,跟服务器交互的时候,就可以直接用 this.$axiosGet( ) ,这样就方便多了。 

总结:主要思路是创建 axios 的实例 axiosInstance,在实例 axiosInstance 上添加请求拦截器和响应拦截器,然后在 axiosInstance 上添加 get 、post等方法。最后在 main.js 中引入,定义到 vue 的原型 prototype 上,方便在 vue 的组件中运用。 

访问本地的json文件

axios 封装成功之后,测试一下访问本地的json文件,看是否能够访问成功。

在vue-cli2.x的版本中,我们习惯在根目录下的 static 文件夹下创建json文件,因为 static目录是vue-cli向外暴露的静态文件夹,全部静态数据都应该放到static目录中!!我们一般会在 static 下新建一个data文件夹,里面放json文件。

但是vue-cli3.x的版本中,没有static文件夹了,那咋办?有人说我创一个static文件夹在下面继续写json文件不就行了。但结果会报错,请求404找不到文件。因为 vue-cli3.x 版本,已经默认将静态文件改存在 public 文件夹下了。此时 public 才是 vue-cli 向外暴露的静态文件夹。所以我们在public下面创建一个json文件夹,里面存放 json 数据的文件。

 此时,我们在文件中就可以测试访问数据了:

let res = await this.$axiosGet('/json/test.json');
console.log(res)

这里可能会有朋友疑问了,诶?请求路径不应该是'public/json/xx.json'吗?注意了如果路径这样写反而会报错404找不到

转发api路径代理设置

开发情况下我们像上面这样改写路径其实是不合理的,默认我们将相对路径写为'/api/xxx',那如何将/api指向实际的数据文件路径,实现转发?旧版本下我们会在vue.config.js下配置proxy属性,但新版本这个js文件已经不在目录下了,我们需要手动创建。

//在根目录下创建vue.config.js,如下配置:
module.exports = {
  devServer: {
    proxy: {  
      '/api': {
        target: 'http://localhost:8080', //路径指向本地主机地址及端口号。这里别忘了加http
        ws: true, 
        changeOrigin: true,
        pathRewrite:{
            '^/api': '/json' //路径转发代理。这里意味着用"/api"来代替"/json"
        }
      }
    }
  }
}

将axios请求路径更改为/api:

let res = await this.$axiosGet('/api/test.json');
console.log(res)

做完以上步骤和避开雷区,已经可以成功在vuecli3、4版本项目上请求到本地json文件的数据了。等到和后台对接时,只要和后台工作人员确认好数据所在的主机地址端口号,更改vue.config.js文件配置即可。

 

有关axios的封装也可参考另一篇: vue项目中axios的封装(简单版)

更多有关axios的细节请移步另一篇文章:https://www.cnblogs.com/smile-fanyin/p/14768579.html

 

posted @ 2021-05-28 10:32  smil、梵音  阅读(1022)  评论(0编辑  收藏  举报