VUE:axios配置及接口请求路径api配置

news/2024/7/10 3:02:37 标签: vue

简介

关于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请求时的服务器地址)

3.1方式一

在项目顶层目录中新建三个文件,分别写入对应的环境配置
在这里插入图片描述
.env.development

NODE_ENV = 'production'	// 打包模式
outputDir = 'dev'	// 要打包到的目录名称
VUE_APP_ENVIRONMENT = 'developmentEnv'	// 区分开发环境、测试环境和生产环境的变量
VUE_APP_BASE_API = 'http://xxx.xxx.xxx:8080'

.env.test

NODE_ENV = 'production'
outputDir = 'test'
VUE_APP_ENVIRONMENT = 'testEnv'
VUE_APP_BASE_API = 'https://xxx.xxx.xxx:8081'

.env.production

NODE_ENV = 'production'
outputDir = 'dist'
VUE_APP_ENVIRONMENT = 'productionEnv'
VUE_APP_BASE_API = 'https://xxx.xxx.xxx:8082'

使用

process.env.VUE_APP_BASE_API
3.2方式二

新建一个放在’/public/'目录下的urlConfig.js文件(当然,其他地方也可以,只是这里可以在打包后进行js文件编辑)

/** 程序/DB版本
 * serverType: D-开发, T-测试, P-正式
 * java/db: 版本号
 */
window.versions = {
  serverType: 'T', // 发布环境
  java: '2.20.220430', // 服务器对应的版本号
  db: '2.06.220602' // 当前项目的版本号
}
console.log(window.versions)

/* ['后台服务地址', '上传文件地址', '生成文件地址'] */
const AllServerAPI = {
  dev: ['http://xxx.xxx.xxx:8080', '', ''],
  test: ['https://xxx.xxx.xxx:8081', '', ''],
  pro: ['https://xxx.xxx.xxx:8082', '', '']
}

/* 每次只需要修改此处,即可配置对应的请求环境 */
const findAPI = AllServerAPI['dev']

/* 服务器请求地址 */
window.serverAPI = {
  baseUrl: findAPI[0],
  uploadUrl: findAPI[1],
  fileUrl: findAPI[2],
}

使用

// 默认主地址
window.serverAPI.baseUrl

// 注意上传、创建等其他服务的请求时,注意修改axios的请求地址即可
window.serverAPI.uploadUrl
window.serverAPI.fileUrl

4.'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: window.serverAPI.baseUrl || '', // 此处即在获取请求的服务器地址
  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;
        },
      },
    });
  },
};

5.'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;
}

6.'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'
  },
};

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

/* 管理相关api
 * @param: key => 子系统名称,用于api/index.js中
 */
export default {
  API_LIST_MANAGEMENT: {
    INTERFACE_GET_ENGINEERINGWORK_LIST: '/engineertype',
    INTERFACE_POST_ENGINEERINGWORK_CREATE: '/admin/engineertype/create',
    INTERFACE_DELETE_ENGINEERINGWORK_DELETE:  '/admin/engineertype/{engineertypeid}',
  },
};

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

vue2x_452">(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');

vue3x_474">(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,就有请求后报错的相关提示。

最后

觉得有用的朋友请用你的金手指点一下赞,或者评论留言一起探讨技术!


http://www.niftyadmin.cn/n/1867213.html

相关文章

170718 python3.x install PIL

PIL P ython I mage L ibrary&#xff0c;最初支持python2.x 在python3.x下下载&#xff0c;则需要&#xff1a; pip install pillow 或 conda install pillow

170719 Keras重复运行结果不一致问题

Github-2743 Github-2479 不同版本的keras,对同样的代码,得到不同结果的原因总结 用深度学习每次得到的结果都不一样,怎么办? 单独设置seed的方法适合于CPU&#xff0c;GPU不适用 指定随机数ShuffleFalse方法&#xff08;认为模型结果的不确定性与采样训练时的随机种子有…

Git:git brash的常用指令

简介 关于git brash的一些常用操作。 具体实现 1.通用步骤 &#xff08;1&#xff09;克隆项目到本地 git clone 地址&#xff08;2&#xff09;拉取文件 git pull&#xff08;3&#xff09;添加所有要提交的文件 git add .&#xff08;4&#xff09;提交日志 git comm…

170720 混淆矩阵绘制+pandas读取数据(有点乱,后面抽空再整理)

Python 数据分析包&#xff1a;pandas 基础 E:\Backup\validation confusion matrix_final2 # -*- coding: utf-8 -*- """ Created on Fri May 19 11:17:12 2017author: Bruce Lau """ #%% import itertools import numpy as np import matplotl…

VUE:项目打包后,如何本地访问

简介 项目打包后&#xff0c;想看一下有没有问题再部署&#xff0c;那么就需要打包后的本地访问&#xff0c;就需要用到插件serve。 具体实现 一、打包 1.正常的打包方式是&#xff1a; npm run build打包成功后&#xff0c;默认的会有一个dist文件夹&#xff0c;里面就是…

170730 Learning materials for D-S and tensorflow-CNN

Python CourseCS231n VideoEnsemble Learning ZhihuDeep learning without a phd VideoCSDNCode D-S Evidence Theory Pdf

JS:格式化时间的方法,及获取指定格式的方法

简介 一些关于时间的获取方法 具体实现 以下是获取时间中部分内容的方法 let time new Date(); time.getYear(); //获取当前年份 time.getFullYear(); //获取完整的年份(4位,1970-???) time.getMonth(); //获取当前月份(0-11,0代表1月) time.getDate(); //获取当前日(1…

java数据类型(类型及转换)

java数据类型 基本数据类型&#xff08;8种&#xff09; 整数类型 byte 一个字节&#xff1a;-128~127short 两个字节int 四个字节long 八个字节 浮点类型 float 四个字节double 八个字节 字符类型 char 两个字节 boolean类型 boolean 一位 引用数据类型 类接口数组…