赞
踩
最近新开一个项目,也是紧急搭了项目架子,做了下封装及分目录,但这回也是发现了一个问题,公共接口地址有多个,简单说下公司的后台,这边后台的接口地址是按模块划分的,常规模式下,后台会给一个公共的接口地址,比如测试的时候公共地址是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"
然后在http.js中
由于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 })
二次封装的loading组件
对样式进行全名处理 /deep/ 是操作ui组件的样式写法,也就是穿透
调用
在你调接口的页面,就直接贴个图了,我这里的@c 是对路径起的别名,在vue.config.js中进行配置
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。