最近新开一个项目,也是紧急搭了项目架子,做了下封装及分目录,但这回也是发现了一个问题,公共接口地址有多个,简单说下公司的后台,这边后台的接口地址是按模块划分的,常规模式下,后台会给一个公共的接口地址,比如测试的时候公共地址是http:ailisi.cn,但后台在这个公共基础上把项目又具体的划分了member,infors ,pay,ticket,lottery 模块,也就是说现在的接口地址需要在http:ailisi.cn这个地址后边分别根据功能拼接上后边的模块,假如说现在需要做登陆注册,而这个功能需要调用的接口是在member模块下,那么最终的接口地址
应该是http:ailisi.cn/member/login 所以这个时候就需要自己处理了,简单截图下项目结构
这里主要说下axios 封装部分,以前我们只有一个公共接口的时候,直接把测试和正式的接口地址写到 .env.development 和 .env,production里,通过process.env.VUE_APP_URL 这个可以获取到你定义的接口的变量值,VUE_APP_URL 这个东西是你自定义的在.env.development这个文件里,格式为VUE_APP_名字 = " http:ailisi.cn " 赋值为你的公共接口地址,这是只有一个公共接口的情况,很好处理。
当出现多个公共接口地址的时候处理,下边是个人处理的一个想法,有好的轻留言讨论
我这边是把axios封装在until文件下的 http.js里,这种情况,我就把 .env.development 和 .env.production文件里的 VUE_APP_URL 的值改为了这样的:
.env.development
VUE_APP_URL = "development"
.env.production
VUE_APP_URL = "production"
由于get请求有时候需要携带参数,所以这里把判断有木有携带参数抽离了出来,这段代码也是搬人家的,大家可以自行搜索,然后我根据模块进行了直接接口封装,member模块就是getmember(),infors模块的就是getinfors(),以此类推,当然你也可以将这个模块名当参数传进去,然后在这个整体的get请求方法里,根据你传入的模块名进行判断走哪个接口,这个你随意
// 分开写实例
// member模块 get 请求
/**
* @param {*} url 接口地址
* @param {*} params 参数
*/
export function getmember(url, params) {
const BASE_URL = api.member + url;
// 返回一个promise
return new Promise((resolve, reject) => {
axios
.get(isHasParams(BASE_URL, params))
.then(response => {
resolve(response);
})
.catch(error => {
reject(error);
});
});
}
// 写一个整体实例
/**
* @param {*} url 接口地址
* @param {*} params 参数
* @param {*} module 模块名
*/
export function getmember(module,url, params) {
const BASE_URL;
// 在这里判断一下你传入的是哪个模块,然后让这个变量接收可以使用switch || if判断
if(module=="member"){
BASE_URL = api.member + url;
}后边的判断逻辑不写了
// 返回一个promise
return new Promise((resolve, reject) => {
axios
.get(isHasParams(BASE_URL, params))
.then(response => {
resolve(response);
})
.catch(error => {
reject(error);
});
});
}
由于我们这边get请求居多,所以我这里都是封装的get请求,当然这里没有把params封装进去,你也可以直接放进去,就是在参数那一块,axios 的get请求是params:参数,post请求是data:参数
isHasParmas方法
/**
* 抽离出来公共方法
*
* 判断 get 请求有木有携带 参数
* @param {*} url 接口地址
* @param {*} params 接口携带参数
*/
function isHasParams(url, params) {
console.log(url);
//判断有木有参数
if (params) {
// 定一个空数组
let paramsArray = [];
// 拆分对象
Object.keys(params).forEach(key =>
paramsArray.push(key + "=" + params[key])
);
//判断是否地址拼接的有没有 ?,当没有的时候,使用 ?拼接第一个参数果有参数拼接,则用&符号拼接后边的参数
if (url.search(/\?/) === -1) {
url = url + "?" + paramsArray.join("&");
} else {
url = url + "&" + paramsArray.join("&");
}
}
//将处理过的接口地址返回去
return url;
}
**最后是引入的配置文件 config.js ** 这里处理的有token过期,请求拦截,响应拦截
说明下,请求拦截也就是你调接口时,接口在响应数据之前做什么,有的小伙伴看完axios的文档,也不知道干啥的,那你就实操代码搞一下子,我们一般都会做个loading
然后,在接口响应后,不管是响应成功 || 失败,都要关闭这个loading,我这边使用的是
muse-ui , muse-ui-loading
https://muse-ui.org/#/zh-CN/
所以直接把它的loading做了二次封装处理,通过vuex 数据仓库 来控制这个隐藏,显示
config.js 代码
import axios from "axios";
import store from "./../store";
//定义loading loading-start 方法
function startLoading() {
// 将数据提交到store里
store.commit("ShowLoading",true)
}
//loading-close 关闭loading方法
function endLoading() {
store.commit("ShowLoading",false)
}
// 请求拦截 设置统一header
axios.interceptors.request.use(
config => {
// 加载
startLoading();
// if (localStorage.eleToken)
// config.headers.Authorization = localStorage.eleToken
return config;
},
error => {
return Promise.reject(error);
}
);
// 响应拦截 401 token过期处理
axios.interceptors.response.use(
response => {
endLoading();
return response;
},
error => {
// 错误提醒
endLoading();
// 这里的token过期处理根据你自己的实际情况来判断,我这边是跟后台定好的
// if (status == 401) {
// Message.error('token值无效,请重新登录')
// // 清除token
// localStorage.removeItem('eleToken')
// // 页面跳转
// router.push('/login')
// }
return Promise.reject(error);
}
);
// get
export default axios;
store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// 存储数据源
const state = {
isShow:false, // 储存loading组件的显示隐藏
}
// 操作state的数据
const mutations = {
ShowLoading(store,plyod){
store.isShow = plyod
}
}
// 操作 muation
const actions = {
}
export default new Vuex.Store({
state,
mutations,
actions
})