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 Design 的 message,就有请求后报错的相关提示。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。
赞 (0)