gitee地址:https://gitee.com/mengxianchen/axios-request-tool
线上体验地址: http://121.43.41.227:82/ 浏览器网络设置成3G 体验效果最佳
一顿操作后
1. vue create excel_demo
2. cd excel_demo
3. npm run serve
效果如下
vue.config.js加上
lintOnSave: false
npm i element-ui
main.js里面加上
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
npm i axios
创建两个按钮分别来演示
未封装时,如何发送get和post请求
可以看出重复的地方很多,像基地址一样,使用的axios属性一样,响应的数据格式一样,都是{code,message,data}
如果项目中请求几百个,后期更新维护会很麻烦
- <div class="box">
- <el-button type="primary" @click="getReq">get请求el-button>
- <el-button type="success" @click="postReq">post请求el-button>
- div>
-
- <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>
封装一个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
导入axios改成导入工具层的request.js
代码优化为↓
- <div class="box">
- <el-button type="primary" @click="getReq">get请求el-button>
- <el-button type="success" @click="postReq">post请求el-button>
- div>
-
- <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.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来修饰
- // 导入接口层方法
- 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);
- },
- },
- };
原理就是发送个自定义请求头参数,请求拦截器里通过判断该参数来控制
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);
- },
- },
完工,各位大佬可以在此基础上优化