gitee地址:/mengxianchen/axios-request-tool
线上体验地址:http://121.43.41.227:82/浏览器网络设置成3G 体验效果最佳
一. 创建一个空的vue2项目
一顿操作后
1. vue create excel_demo
2. cdexcel_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 iaxios
三. 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-/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);},},
完工,各位大佬可以在此基础上优化
如果觉得《如何封装axios请求。统一基地址 加载遮罩层 响应参数优化》对你有帮助,请点赞、收藏,并留下你的观点哦!