vue中的axios配置及接口请求路径api配置

目录
  • 简介
  • 一、axios配置
  • 二、请求接口路径api配置
  • 三、axios和接口api的全局注入
  • 四、请求接口的使用方式
  • 注意

简介

关于vue中使用axios请求的配置,注意其中区分Vue2.0和Vue3.0的写法

一、axios配置

由于可能会有多个插件应用,所以有了plugins(utils里面放的是封装的事件处理方法),自行新建相关文件

1.安装axios

npm install axios --save

2.‘plugins/index.js’ 配置

// 导出所有插件
let moduleFiles = require.context('./modules', true, /\.js$/);
export default moduleFiles;

3.'axios.js’配置

'use strict';
import axios from 'axios';
// import store from "@/store";
// import { message } from "ant-design-vue"
import { getAllPromise } from '@/utils/tools';
import { triggerEvent } from '@/utils/events';
// 完整配置参考:  https://github.com/axios/axios#request-config
axios.defaults.headers.post['Content-Type'] = 'application/json;charset=utf-8';
axios.defaults.headers.put['Content-Type'] = 'application/json;charset=utf-8';
axios.defaults.headers.delete['Content-Type'] =
  'application/json;charset=utf-8';
let config = {
  baseURL: process.env.VUE_APP_BASE_API || process.env.apiUrl || '',
  timeout: 60 * 1000,
  withCredentials: false,
  crossDomain: true,
  transformRequest: [
    (data) => {
      if (!data || typeof data === 'string') {
        return data;
      }
      if (data instanceof FormData) {
        return data;
      }
      // 对Blob对象进行处理
      let hasBlob = Object.values(data).some((it) => {
        return it instanceof Blob;
      });
      if (!hasBlob) {
        return JSON.stringify(data);
      }
      const formData = new FormData();
      Object.entries(data).forEach(([key, value]) => {
        formData.append(key, value);
      });
      return formData;
    },
  ],
};
const _axios = axios.create(config);
// 注册all方法,执行多个并发请求
// 可传入Promise、包含Promise的数组、返回值为Promise的方法
_axios.all = (...requsets) => {
  // 获取所有Promise对象
  let promiseList = getAllPromise(requsets);
  return new Promise((resolve, reject) => {
    axios
      .all(promiseList)
      .then(
        axios.spread((...response) => {
          // 两个请求现在都执行完成
          resolve(response);
        })
      )
      .catch((error) => {
        reject(error);
      });
  });
};
_axios.interceptors.request.use(
  (config) => {
    // const token = getCookie(AUTH_TOKEN_FRONT);
    // config.headers.common[AUTH_TOKEN_END] = token;
    const token = 'AUTH_TOKEN_FRONT';
    config.headers.common.Token = token;
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);
// 拦截响应
_axios.interceptors.response.use(
  (response) => {
    // console.log(response)
    // 用来判断是否请求成功
    const success = response.status === 200;
    let messages = '';
    if (!success) {
      if (typeof response.data === 'string') {
        messages = '服务器错误,未获取到响应数据';
      } else {
        if (response.status === 200) {
          return Promise.reject(response);
        }
        // 请求成功,但在业务上为失败
        messages = response.message || response.statusText || '操作执行失败';
      }
      console.error(messages);
      return Promise.reject(response);
    }
    return {
      data: response.data,
      success,
      messages,
    };
  },
  (error) => {
    if (!navigator.onLine) {
      triggerEvent(window, 'offline');
      return Promise.reject(error);
    }
    if (!error.response) {
      console.error('连接服务器失败');
      return Promise.reject(error);
    }
    let status = error.response.status;
    if (status === 401) {
      // message.error("您的登录已过期,请重新登录");
      // window.location.reload();
      // store.dispatch("user/logout");
      return Promise.reject(error);
    }
    if (status < 200) {
      console.warning(`未处理的消息响应,状态码:${status}`);
    } else if (status >= 300 && status < 400) {
      console.warning(`未处理的重定向响应,状态码:${status}`);
    } else if (status >= 400 && status < 500) {
      console.error(`客户端错误,状态码:${status}`);
    } else if (status >= 500) {
      console.error(`服务器错误,状态码:${status}`);
    }
    // 系统请求失败
    return Promise.reject(error);
  }
);
// -------------------------vue2.x导出-------------------------
// export default {
//   install: (Vue) => {
//     Vue.$_http = _axios;
//     window.$_http = _axios;
//     Object.defineProperties(Vue.prototype, {
//       $_http: {
//         get() {
//           return _axios;
//         },
//       },
//     });
//   },
// };
// -------------------------vue3.x导出-------------------------
export default {
  install: (app) => {
    app.$_http = _axios;
    window.$_http = _axios;
    Object.defineProperties(app.config.globalProperties, {
      $_http: {
        get() {
          return _axios;
        },
      },
    });
  },
};

4.'utils/tools.js’配置

/**
 * 从参数中获取所有Promise对象,组成数组并返回
 * @param  {...any} datas 待解析数据
 */
export function getAllPromise(...datas) {
  let promiseList = [];
  datas.forEach((it) => {
    if (isDataType(it, 'Promise')) {
      promiseList.push(it);
      return;
    }
    // 是方法则获取执行的结果
    if (isDataType(it, 'Function')) {
      promiseList.push(...getAllPromise(it()));
      return;
    }
    if (isDataType(it, 'Array')) {
      promiseList.push(...getAllPromise(...it));
    }
  });
  return promiseList;
}
/**
 * 判断数据的类型是否符合预期
 * 只传一个参数data,则返回数据的类型;
 * 传入多个参数,则判断数据是否属于该类型(或属于类型数组中的一个)
 * @param {*} data 需要判断类型的数据
 * @param  {...any} typeList 字符串或字符串数组,可不传
 */
export function isDataType(data, ...typeList) {
  let dataType = Object.prototype.toString
    .call(data)
    .replace(/^\[object/, '')
    .replace(/\]$/, '')
    .replace(/\s/, '');
  typeList = flat(typeList);
  let hasType = typeList.some((it) => {
    return it && isDataType(it) === 'String';
  });
  if (!hasType) {
    return dataType;
  }
  if (
    typeList.includes(dataType) ||
    typeList.includes(dataType.toLowerCase())
  ) {
    return true;
  }
  return false;
}
/**
 * Array.flat在app和Trident内核上会报错,重写
 * @param {Array} list 目标数组
 */
export function flat(list) {
  if (Array.prototype.flat) {
    return list.flat(Infinity);
  }
  let retArr = [];
  if (!Array.isArray(list)) {
    throw new Error(
      `Invalid parameter: type check failed for parameter 'list'. Expected Array, But got ${typeof list} with value ${list}`
    );
  }
  list.forEach((it) => {
    if (!Array.isArray(it)) {
      retArr.push(it);
      return;
    }
    retArr.push(...flat(it));
  });
  return retArr;
}

5.'utils/events.js’配置

// 浏览器中的事件管理
/**
 * 触发一个DOM事件
 * @param  {Element} node 事件发生的节点元素
 * @param  {String} name 事件名称,不含前缀:on
 * @param  {...any} options 可选的事件配置项
 */
export function triggerEvent(node, name, ...options) {
  if (node.fireEvent) {
    return node.fireEvent('on' + name);
  }
  let eventName;
  let evt;
  if (/^mouse|click/.test(name)) {
    eventName = 'MouseEvents';
    evt = document.createEvent(eventName);
    evt.initMouseEvent(name, ...options);
  } else if (['DOMActivate', 'DOMFocusIn', 'DOMFocusOut'].includes(name)) {
    eventName = 'UIEvents';
    evt = document.createEvent(eventName);
    evt.initUIEvent(name, ...options);
  } else if (/^key/.test(name)) {
    eventName = 'KeyboardEvent';
    evt = document.createEvent(eventName);
    evt.initKeyboardEvent(name, ...options);
  } else if (name.startsWith('DOM')) {
    eventName = 'MutationEvents';
    evt = document.createEvent(eventName);
    evt.initMutationEvent(name, ...options);
  } else {
    eventName = 'HTMLEvents';
    evt = document.createEvent(eventName);
    evt.initEvent(name, ...options);
  }
  return node.dispatchEvent(evt);
}

二、请求接口路径api配置

自行根据目录结构新建文件。

方便区分接口所属模块,于是根据接口分类进行新建js文件。

1. api集合中心(‘api/index.js’)

'use strict';
/* eslint-disable no-unused-vars */
/** 有几个模块,subList就有几个元素
 * @param: name 子系统名称
 * @param: url 子系统使用的环境变量(请求地址,便于不同模块请求不同服务器的配置,可在三个环境中新增类似VUE_APP_BASE_API的域名地址变量)
 */
const subList = [
  {
    name: 'API_LIST_USER',
    url: 'VUE_APP_BASE_API',
  },
  {
    name: 'API_LIST_MANAGEMENT',
    url: 'VUE_APP_BASE_API',
  },
];
// 所有api子系统
let API_LIST = {};
const moduleFiles = require.context('./modules', true, /\.js$/);
moduleFiles.keys().forEach((modulePath) => {
  API_LIST = { ...API_LIST, ...moduleFiles(modulePath).default };
});
// 合成API地址集合
let apiList = {};
subList.forEach((it) => {
  let subApi = Object.entries(API_LIST[it.name]).reduce(
    (target, [key, value]) => {
      target[key] = process.env[it.url].replace(/\W*$/, '') + '/' + value.replace(/^\W*/, '');
      return target;
    },
    {}
  );
  apiList = { ...apiList, ...subApi };
});
export default apiList;

2. 模块分类一:user(‘api/user.js’)

/* 用户相关api */
export default {
  API_LIST_USER: {
    // 登录
    INTERFACE_GET_USER_LOGIN: 'user/login',
    // 查询管理员列表
    INTERFACE_GET_USER_LIST: 'admin/users',
    // 新增管理员
    INTERFACE_POST_USER_ADMIN: 'admin/register',
    // 删除管理员
    INTERFACE_DELETE_USER_ADMIN: 'admin/users',
  },
};

3. 模块分类二:管理(‘api/management.js’)

/* 管理相关api
 * @param: key => 子系统名称,用于api/index.js中
 */
export default {
  API_LIST_MANAGEMENT: {
    // 工种列表
    INTERFACE_GET_ENGINEERINGWORK_LIST: '/engineertypes',
    // 新建工种
    INTERFACE_POST_ENGINEERINGWORK_CREATE: '/admin/engineertype',
    // 删除工种
    INTERFACE_DELETE_ENGINEERINGWORK_DELETE:  '/admin/engineertype/{engineertypeid}',
  },
};

三、axios和接口api的全局注入

(1)vue2.x

import Vue from 'vue';
import App from './App.vue';
// 注册自定义插件
import moduleFiles from './plugins';
// 引入api地址
import apiList from '@/api';
// 批量使用自定义插件
moduleFiles.keys().forEach(modulePath => {
  Vue.use(moduleFiles(modulePath).default);
});
// 注册所有api地址为全局变量
Vue.prototype.$_API = apiList;
new Vue({
  render: (h) => h(App),
}).$mount('#app');

(2)vue3.x

import { createApp } from 'vue';
import App from './App.vue';
// 引入自定义插件
import moduleFiles from './plugins';
// 引入api地址
import apiList from '@/api';
const app = createApp(App);
app.mount('#app');
// 注册所有api地址为全局变量
app.config.globalProperties.$_API = apiList;
// 批量使用自定义插件
moduleFiles.keys().forEach((modulePath) => {
  app.use(moduleFiles(modulePath).default);
});

四、请求接口的使用方式

以下是vue2.x的使用方式

// 其中 url为接口地址,在api目录下定义
// config内容为参数和其他配置,例如:
--------------------------执行 GET 请求---------------------------------
// 执行 GET 请求
this.$_http.get('url' + "?ID=12345")
  .then(response => {
    // 自己的操作
    console.log(response);
  })
// 不需要写catch,axios配置会自动提示出来
// 可选地,上面的请求可以这样写
this.$_http.get('url', {
    params: {
      ID: 12345
    }
  }).then(response => {
    // 自己的操作
    console.log(response);
  })
--------------------------执行 POST 请求---------------------------------
// 执行 POST 请求
this.$_http.post('url', {
  firstName: "Fred",
  lastName: "Flintstone"
}).then(response => {
  // 自己的操作
  console.log(response);
})
--------------------------执行 DELETE 请求---------------------------------
// 执行 POST 请求
this.$_http.delete('url', {
  data: { id: 1 }
}).then(response => {
  // 自己的操作
  console.log(response);
})
--------------------------案例---------------------------------------------
let params = {
  page: 0,
  size: 10,
};
this.$_http.get(this.$_API.INTERFACE_GET_USER_LIST, { params }).then((res) => {
  console.log(res);
});

以下是vue3.x的使用方式

import { getCurrentInstance } from "vue"
setUp() {
  // 方式一
  // const internalInstance = getCurrentInstance()
  // const globalProperties = internalInstance.appContext.config.globalProperties
  // const _http = globalProperties.$_http
  // const _API = globalProperties.$_API
  // 方式二
  const { proxy } = getCurrentInstance()
  const _http = proxy.$_http
  const _API = proxy.$_API
  console.log(_http, _API)
  let params = {
    page: 0,
    size: 10,
  }
  _http.get(_API.INTERFACE_GET_USER_LIST, { params }).then((res) => {
    console.log("axios请求结果", res);
  })
}

注意

axios.js 中,关于 console.error 相关的部分,替换为自己项目所引入的ui框架的消息提示即可,如 ant Designmessage,就有请求后报错的相关提示。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • vue封装axios与api接口管理的完整步骤

    目录 一.前言 二.axios封装步骤 三.api接口统一管理 总结 一.前言 axios的封装和api接口的统一管理,其实主要目的就是在帮助我们简化代码和利于后期的更新维护. 二.axios封装步骤 安装:npm install axios -S 一般我会在项目的src目录中,新建一个network文件夹,作为我们的网络请求模块,然后在里面新建一个http.js和一个api.js文件和一个reques.js.http.js文件用来封装我们的axios,api.js用来统一管理我们的接口url,

  • axios接口管理优化操作详解

    目录 强化功能 接口文件写法简化 任务调度.Loading调度 提示信息自由化 总结 强化功能 本文针对中大型的后台项目的接口模块优化,在不影响项目正常运行的前提下,增量更新. 接口文件写法简化(接口模块半自动化生成) 任务调度.Loading调度(接口层面的防抖兜底,多个接口共用一个loading,防止闪烁) 接口提示自由化(提示消息可由前端控制,也可以由后端控制) 接口文件写法简化 对于一些中后台模块的接口,基本上都是增删改查以及审核流的一些功能(其他特殊接口暂且不谈).如果后端接口足够规范

  • Vue路由切换和Axios接口取消重复请求详解

    目录 前言 场景 解决方案 axios中如何取消请求 项目中封装使用 总结 参考 前言 在日常前端开发中, 经常会遇到频繁发起的重复请求, 会给服务器及网络造成不必要的压力, 可通过取消重复请求解决 场景 订单数据条件筛选查询 表单提交按钮频繁点击 路由页面切换请求未取消 解决方案 在每个请求发起的时候存储当前存储的标记在一个数组或Map中, 针对每个请求的时候在请求拦截中查询是否重复, 如果已重复则取消历史中重复的请求, 再发起当前请求, 如果没有重复, 则添加存储标记并正常请求, 已请求完成

  • Vue中Axios的封装与接口管理详解

    目录 一. Axios 的封装 安装 Axios 引入 接口管理 统一暴露接口 在组件中使用 补充:封装get方法和post方法 总结 一. Axios 的封装 在 Vue 项目中,和后台进行数据交互是频繁且不可或缺的,刚开始没进行 Axios 封装的时候,每次请求后台数据都是写的完整的路径,特别长,尤其是基准地址,每次都要复制一遍加在前面,冗余特别大.封装完 Axios 后,调用接口就简短多了,如果后期出现基准地址的改变,只需要在配置中更改一次即可. 安装 Axios npm install

  • 详解基于 axios 的 Vue 项目 http 请求优化

    对于需要大量使用 http 请求的项目,我们通常会选择对 http 请求的方法进行二次封装,以便增加统一的拦截器,或者统一处理阻止重复提交之类的逻辑.Vue.js 的项目中我们选择使用了 axios 这样一个 http 库,下面也就简述下基于 axios 做的简单二次封装 依赖 首先引入 axios ,对于 ie9 这样不支持 promise 的浏览器还需引入 es6-promise 模块 require('es6-promise').polyfill(); var axios = requir

  • Vue+axios实现统一接口管理的方法

    通过axios请求接口已经很简单了,但最近在做一个vue项目,想着把axios请求再封装一下,这样api就可以只在一处配置成方法,在使用的时候直接调用这个方法. 但咱们不用每个接口都定义成一个啰嗦的axios请求方法,既然是想简单点,就尽量只在一处完成简单的配置. 1.配置api接口 将同一模块的接口放在一个文件下,比如我在src的services下定义了一个global.js作为全局服务的配置,在它里面配置的api可以作为这个服务的方法. 比如: name字段将作为之后被调用的方法名,但这个只

  • Vue3引入axios封装接口的两种方法实例

    目录 第一种 1.安装 2.新建一个http.js文件 3.使用 第二种 1.安装 2.新建 3.http.js 4.request.js 总结 第一种 1.安装 npm install axios -S 2.新建一个http.js文件 import axios from "axios"; import qs from "qs"; import { Dialog, Toast } from "vant"; // axios.defaults.ba

  • Vue中使用axios调用后端接口的坑及解决

    目录 axios调用后端接口的坑 问题场景 总结了如下场景 调用后端接口 使用axios跨域问题 首先找到项目中vue.config.js axios调用后端接口的坑 问题场景 Vue.js工程中使用axios调用后端接口(SpringBoot构建)出现后端接口无法获得数据的情况 总结了如下场景 @RequestParam用来处理application/x-www-form-urlencoded编码(HTTP协议请求头中不指定Content-Type默认就是application/x-www-f

  • 详解vue中使用axios对同一个接口连续请求导致返回数据混乱的问题

    业务上出现一个问题:如果连续对同一个接口发出请求,参数不同,有时候先请求的比后请求的返回数据慢,导致数据顺序混乱,或者数据被覆盖的问题,所以需要控制请求的顺序. 解决方法: 1.直接跟后台沟通,将所有参数放到数组里后台统一接收并返回所有数据再由前端进行数据的拆分使用. 2.对于出现返回的数据混乱问题. 假设场景: 页面中需要对三个部门请求对应的部门人员,三个部门人员的数据为一个二维数组,连续发送请求,但由于返回数据的顺序不定,导致数组中的数据顺序不是按照部门的顺序. 解决方法:使用promise

  • 解决在Vue中使用axios POST请求变成OPTIONS的问题

    POST请求变成OPTIONS 及报错信息(跨域) 主要解决方案:使用qs.stringify 1.安装qs npm install qs --save 2.axios配置和使用 在接口请求页面引入安装好的qs,如下图: 引入完成之后使用qs改变传递的参数data,如下: 这样就可以了,post请求的时候就不会再出现OPTIONS了 补充知识:axios发起请求,为什么先发送options请求,再发送get/post请求 引起原因 1,跨域: 2,请求头非默认情况. 默认请求头如下 Accept

  • vue中封装axios并实现api接口的统一管理

    在vue项目中,我们通常都是使用axios与后台进行数据交互,axios有很多好用的特性,这里不多做介绍,相关细节可以查阅axios中文网.在对axios进行封装之前,我们要使用vue脚手架工具创建一个vue项目(这里我用的是cli4). 安装 cnpm install axios --save-dev; // 安装axios cnpm install qs --save-dev; // 安装qs模块,用来序列化post类型的数据,否则后端无法接收到数据 模块引入 在src目录下创建一个serv

  • 在Vue中使用axios请求拦截的实现方法

    一.前言 axios的基础使用就不过多的讲解啦,如何使用可以看axios文档使用说明·Axios中文说明 在这里和大家分享一下axios拦截在实际项目中的使用 很多人都看过axios的官方文档中拦截器这一栏,有的人可能会有点懵,因为文档只告诉你有这个东西,而不告诉你在什么情况下使用.很多初学者就会放弃使用axios拦截器,毕竟拦截器是可以不使用的,但是使用拦截器,会在页面中减少很多不必要的代码. 二.说在前面的 项目使用的ui框架是iview 以下友好提示均使用iview ui的message提

  • 解决vue中使用Axios调用接口时出现的ie数据处理问题

    1.问题 近期在使用vue2 + axios 调用接口时碰到一个IE中很奇葩的问题,让我头痛了很久. 废话不多扯,就是在其他浏览器中调用接口返回数据然后可以很顺利的进行处理,但在IE(9-11)中发现发送请求是成功的而且也能抓到服务端返回来的数据.却发现在处理返回来的数据的时候处理的有点问题,怎么搞就是不行. 2.处理过程及方法 我使用了console大法去解决这个问题,具体是这样的:我先将服务器返回过来的数据打印到浏览器控制台,结果发现都能打印出来,这个时候就郁闷了,明明有数据为何在IE上还是

  • vue axios数据请求及vue中使用axios的方法

    axios 简介 axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,它本身具有以下特征: -------------------------------------------------------------------------------- •从浏览器中创建 XMLHttpRequest •从 node.js 发出 http 请求 •支持 Promise API •拦截请求和响应 •转换请求和响应数据 •取消请求 •自动转换JSON数据 •客户端支

  • 在vue中使用jsonp进行跨域请求接口操作

    前言: 这里我们使用的是第三方插件jsonp. github网址:https://github.com/webmodules/jsonp 1.安装 npm install jsonp -S 2.引入 一般新建一个js文件来引入原始jsonp插件,然后对原始插件进行封装,对跨域接口参数的拼接,封装好这个jsonp文件后export出去,之后在哪里用到就再在那里import. 1.新建jsonp.js文件来封装原始jsonp插件 // 引入原始jsonp插件 import originJsonp f

  • vue+axios实现文件下载及vue中使用axios的实例

    功能:点击导出按钮,提交请求,下载excel文件: 第一步:跟后端童鞋确认交付的接口的response header设置了 以及返回了文件流. 第二步:修改axios请求的responseType为blob,以post请求为例: axios({ method: 'post', url: 'api/user/', data: { firstName: 'Fred', lastName: 'Flintstone' }, responseType: 'blob' }).then(response =>

  • vue简单封装axios插件和接口的统一管理操作示例

    本文实例讲述了vue简单封装axios插件和接口的统一管理操作.分享给大家供大家参考,具体如下: 现在很多公司的项目都是前后端分离的项目,那么说到前后端分离,必定会有ajax请求来获得后台的数据. 在做jquery项目的时候,我们都会使用它封装好的方法来直接发起ajax请求. 在vue项目中,我们使用最多的就是axios这个插件,下面就简单的封装下这个插件并且把接口给统一化管理. 一.安装和配置 1.在项目根目录下打开终端安装 npm install axios -S 2.安装完成以后,在src

随机推荐