gitee地址:https://gitee.com/mengxianchen/axios-request-tool 

线上体验地址: http://121.43.41.227:82/   浏览器网络设置成3G 体验效果最佳

一. 创建一个空的vue2项目

 一顿操作后

1. vue create excel_demo

2. cd excel_demo

3. npm run serve

效果如下

  

二. 前期准备

1. 关闭eslint检查

vue.config.js加上 

lintOnSave: false

2.安装插件 element-ui

npm i element-ui

main.js里面加上 

import ElementUI from 'element-ui';

import 'element-ui/lib/theme-chalk/index.css';

Vue.use(ElementUI);

2. 安装插件axios        

npm i axios

三. src/App.vue的内容替换成以下代码

创建两个按钮分别来演示

未封装时,如何发送get和post请求

可以看出重复的地方很多,像基地址一样,使用的axios属性一样,响应的数据格式一样,都是{code,message,data}

如果项目中请求几百个,后期更新维护会很麻烦

<template>
  <div class="box">
    <el-button type="primary" @click="getReq">get请求</el-button>
    <el-button type="success" @click="postReq">post请求</el-button>
  </div>
</template>

<script>
// 导入axios用来发请求
import axios from "axios";

export default {
  name: "App",
  components: {},
  methods: {
    // 发送get请求
    getReq(){
      axios({
        method:'get',
        url:'https://www.fastmock.site/mock/7a24fbd3721a2bb3ca8b81050909b081/login/api/getUser',
      })
        .then(getRes => {
          console.log(getRes);
          this.$message.success(getRes.data.message)
      });
    },

    // 发送post请求
    postReq(){
      axios({
        method:'post',
        url:'https://www.fastmock.site/mock/7a24fbd3721a2bb3ca8b81050909b081/login/api/updUser',
        data:{ p1 :'参数1', p2 :'参数2'}
      })
        .then(postRes => {
          console.log(postRes);
          this.$message.success(postRes.data.message)
      });
    },
  },
};
</script>

<style>
.box{
  margin: 100px 500px;
}
</style>

四. 在src目录下新建 utils/request.js

封装一个axios实例,导出去供人使用

该工具实现了

1. 统一基地址

2. 每次发送请求出现加载遮罩层,响应数据后关闭遮罩层

3. 优化响应数据格式,降低复杂度

import axios from "axios"
import { Loading } from 'element-ui';

// 封装自定义axios实例
const serve = axios.create({
    // 设置基地址
    baseURL:'https://www.fastmock.site',
})
let loadingInstance
// 请求拦截器
serve.interceptors.request.use(function (config) {

    // 开启加载弹窗
    loadingInstance = Loading.service({ fullscreen: true });
    // console.log('开启弹窗',loadingInstance);
    
    return config;
}, function (error) {
    return Promise.reject(error);
});
// 响应拦截器
serve.interceptors.response.use(function (response) {

    // 关闭加载弹窗 
    // 如果响应过快需要将浏览器Network里网络设置成3G,才能看到加载效果
    loadingInstance.close();

    console.log('减少复杂度之前的响应数据',response);

    // 优化响应数据格式,减少复杂度
    return {
        code: response.data.code,
        message: response.data.message,
        data: response.data.data,
    }
}, function (error) {
    return Promise.reject(error);
});

export default serve

五. 在App.vue使用

导入axios改成导入工具层的request.js

代码优化为↓

<template>
  <div class="box">
    <el-button type="primary" @click="getReq">get请求</el-button>
    <el-button type="success" @click="postReq">post请求</el-button>
  </div>
</template>

<script>
// 导入axios工具文件用来发请求
import request from "@/utils/request";

export default {
  name: "App",
  components: {},

  // 封装请求工具优化后↓↓↓
  methods: {
    // 发送get请求
    async getReq() {
      const res = await request({
        url: "/mock/7a24fbd3721a2bb3ca8b81050909b081/login/api/getUser",
      });
      console.log(res);
      this.$message.success(res.message);
    },

    // 发送post请求
    async postReq() {
      const res = await request({
        url: "/mock/7a24fbd3721a2bb3ca8b81050909b081/login/api/updUser",
        method: "post",
        data: { p1: "参数1", p2: "参数2" },
      });
      console.log(res);
      this.$message.success(res.message);
    },
  },
};
</script>

<style>
.box {
  margin: 100px 500px;
}
</style>

看到这里 ,一部分长得好看的小伙伴,会想到当前代码可以再分一个 接口层

六. 再次解耦,请求都放到接口层 创建目录src/api/user/user.js

src 下创建 api/user.js

import request from '@/utils/request'


export function apiGet(){
    return request({
        url: '/mock/7a24fbd3721a2bb3ca8b81050909b081/login/api/getUser',
        method: 'get'
    })
}

export function apiPost(data){
    return request({
        url: '/mock/7a24fbd3721a2bb3ca8b81050909b081/login/api/updUser',
        method: 'post',
        data
    })
}

这里的传参可能不好理解! 为什么参数传了 url和method  能在 utils/request.js 里用?

utils/request.js 里并没有写接收这两个参数的代码。

因为 utils/request.js 导出的是一个自定义配置的axios实例,给它传参数等于在给它进行自定义配置。 具体能传哪些参数 参考axios文档: http://www.axios-js.com/zh-cn/docs/#axios-create-config

 

app.vue代码优化。 script标签覆盖为以下代码

此时页面效果一样,导入接口的方法后,仅一行代码就能发送请求。

记得加 async await来修饰

<script>
// 导入接口层方法
import {apiGet,apiPost} from "@/api/user";

export default {
  name: "App",
  components: {},

  // 封装请求工具优化后↓↓↓
  methods: {
    // 发送get请求
    async getReq() {
      const res = await apiGet();
      console.log(res);
      this.$message.success(res.message);
    },

    // 发送post请求
    async postReq() {
      const res = await apiPost({ p1: "参数1", p2: "参数2" });
      console.log(res);
      this.$message.success(res.message);
    },
  },
};
</script>

七. 优化遮罩层 请求时控制是否使用

原理就是发送个自定义请求头参数,请求拦截器里通过判断该参数来控制

utils/request.js 中请求拦截器和响应拦截器 的代码优化如下

// 请求拦截器
serve.interceptors.request.use(function (config) {

    console.log('请求头',config.headers);
    // 请求头中接收参数 是否加载遮罩层弹窗()
    const isLoading = config.headers.isLoading
    // isLoading存在 则开启遮罩层弹窗
    isLoading ? loadingInstance = Loading.service({ fullscreen: true }) : null

    // console.log('开启弹窗',loadingInstance);
    
    return config;
}, function (error) {
    return Promise.reject(error);
});
// 响应拦截器
serve.interceptors.response.use(function (response) {

    
    // 如果响应过快需要将浏览器Network里网络设置成3G,才能看到加载效果
    // 关闭遮罩层弹窗(如果有)  
    loadingInstance && loadingInstance.close(); 

    console.log('减少复杂度之前的响应数据',response);

    // 优化响应数据格式,减少复杂度
    return {
        code: response.data.code,
        message: response.data.message,
        data: response.data.data,
    }
}, function (error) {
    return Promise.reject(error);
});

api/user.js 代码优化如下

import request from '@/utils/request'

export function apiGet(isLoading = false){
    return request({
        url: '/mock/7a24fbd3721a2bb3ca8b81050909b081/login/api/getUser',
        method: 'get',
        headers:{ isLoading }
    })
}

export function apiPost(data, isLoading = false){
    return request({
        url: '/mock/7a24fbd3721a2bb3ca8b81050909b081/login/api/updUser',
        method: 'post',
        data,
        headers:{ isLoading }
    })
}

App.vue 中 methods里的方法  优化如下

用法:只需要传 bool值 

 true 或 1 或其他会隐式转化为true的值都可以  都会触发遮罩层 !

methods: {
    // 发送get请求
    async getReq() {
      const res = await apiGet(true);
      console.log(res);
      this.$message.success(res.message);
    },

    // 发送post请求
    async postReq() {
      const res = await apiPost({ p1: "参数1", p2: "参数2" }, true);
      console.log(res);
      this.$message.success(res.message);
    },
  },

完工,各位大佬可以在此基础上优化

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐