VUE使用axios封装RESTful风格
本文章讲述axios的使用、封装代码、restful风格、接口定义规则知识点。可以根据本文章拓展自己的业务。源代码
文章目录
前言
在前后端分离的开发我们来看以下几个问题,这也是为什么写这篇文章
1、为什么我们要用restful风格呢?
- 我们对应增删改查是要有一个请求规范(也是约束)查询是get,删除是delete,修改是put,添加时post。
- 具有扩展性强、结构清晰的特点
2、为什么封装axios?
- 减少代码冗余
- 拓展性强,结构清晰
- 遵守restful风格装饰axios
- 多个项目可重用封装好的axios,只需引用js文件
一、使用axios
1.代码
import Vue from "vue";
import axios from 'axios';
import qs from "qs";
/**
* 读取配置文件
*/
axios.get('../static/config.json', {
timeout: 5000,
headers: {'Content-type': 'multipart/form-data'}
}).then(res => {
console.log("read config");
axios.defaults.baseURL = res.data.baseURL;
axios.defaults.withCredentials = true;
Vue.prototype.$axios = axios;
//验证token
localStorage.setItem('oauth', res.data.oauth);
// 通用参数
Vue.prototype.param = {
oauth: res.data.oauth,//授权值
baseURL: res.data.baseURL,//请求url
url: res.data.paramUrl,//拓展使用的url
version: res.data.version,//显示的版本号
pagesize: 8,
/**
* 新定义的组key要放在prototype.blockurl()调用否则不生效
* 数组第一个必须是组名,其余为controller名称,新增一个controller时要放在最后位置不能随意插入
* 例如:[组名,controller名,controller名,controller名...]
* 如果组里面的接口重复可以使用关键字让代码帮助你区分,组名@接口名
*/
//订单
oms: ['oms', 'order/v2', 'payType/v2','oms@member/v2'],
//会员
ums: ['ums', 'ums@member/v2', 'grade/v2']
};
}).catch(err => {
console.log('read config err' + err)
});
2.知识点
- 读取配置文件可以在打成dist后修改
static/config.json
来改变页面需要请求环境不需要在重新打包。配置文件的拓展性是很强的但是不要存放一些敏感数据 - Vue.prototype.param里定义了oms、ums两个key值这个是接下来要讲的第四章节
二、使用axios.interceptors(拦截器)
1.代码
axios.interceptors.request.use(
config => {
//传送验证token
let token = localStorage.getItem('token') == null || localStorage.getItem('token') === '' ? localStorage.oauth : ('bearer ' + localStorage.token);
// console.log('this token' + token);
//判断是否有token
if (token) {
config.headers['Authorization'] = token;
}
return config;
},
err => {
return Promis.reject(err);
}
)
2.知识点
- 这里实现了拦截request实现获取缓存
- 使用headers,就不用在每个不同的请求协议里写headers从而减少代码冗余
三、封装restful请求方法
1.代码
Vue.prototype.mypostv2 = function (url, data, success, error, json) {
let req = null;
//是否传输json
if (json) {
req = data;
} else {
req = qs.stringify(data);
}
url = this.assembleURL(url);
this.$axios
.post(url, req, {
timeout: 200000,
}).then(res => {
this.myResponse(res, success, error);
})
.catch(err => {
this.myCatch(err);
});
};
Vue.prototype.mygetv2 = function (url, req, success, error, json) {
this.$axios
.get(this.assembleURL(url), {
params: req,
timeout: 200000,
})
.then(res => {
this.myResponse(res, success, error);
})
.catch(err => {
this.myCatch(err);
});
};
Vue.prototype.myputv2 = function (url, data, success, error, json) {
let req = null;
//是否传输json
if (json) {
req = data;
} else {
req = qs.stringify(data);
}
this.$axios.put(this.assembleURL(url), req, {timeout: 200000})
.then(res => {
this.myResponse(res, success, error);
})
.catch(err => {
this.myCatch(err);
});
};
Vue.prototype.mydeletev2 = function (url, req, success, error, json) {
this.$axios
.delete(this.assembleURL(url), {params: req, timeout: 200000})
.then(res => {
this.myResponse(res, success, error);
})
.catch(err => {
this.myCatch(err);
});
};
/**
* 通用处理response
* @param res
* @param success
* @param error
*/
Vue.prototype.myResponse = function (res, success, error) {
//验证码返回的res
if (res.headers['content-type'] === "image/jpeg") {
return success(res);
}
//验证token返回的res
if (res.data.access_token) {
return success(res);
}
//有返回success,code字段就可以判断业务报错
if (res.data.code === '00000' && res.data.success) {
if (success) {
return success(res);
}
} else {
//是否使用错误回调
if (error) {
error(res)
} else {
//自动处理错误信息,有code字段就可以判断业务报错
if (res.data.code) {
this.$message({
message: res.data.msg,
type: "error"
});
} else {
this.$message({
message: '未解析到的错误',
type: "error"
});
}
}
}
};
/**
* 处理请求报错
* @param err
*/
Vue.prototype.myCatch = function (err) {
//TODO 处理你的报错
};
2.知识点
- mypostv2:实现
this.$axios.post
协议,用于添加 - mygetv2:实现
this.$axios.get
协议,用于查询 - myputv2:实现
this.$axios.put
协议,用于修改 - mydeletev2:实现
this.$axios.delete
协议 ,用于删除 - 组装请求的url
this.assembleURL(url)
请看第四章节 - myResponse、myCatch:处理请求回来的资源
四、封装后端接口
Vue.prototype.param里定义了oms、ums两个key值,目的是减少修改文件的地方,比如后端改了一个接口名或者我要使用第二个版本的接口,那么我在这里就能实现修改一个地方就无需修改其余使用此接口名的文件
1.接口定义规则
- 前后端都要遵守接口命名规则 /项目名/业务组名/controller/操作名 例如:
/admin/ums/grade/list
(后端定义一个接口的版本号可以放在controller后面这样不用破坏一个文件的版本完整性 /项目名/业务组名/controller/版本号/操作名) - 一个key对应一个业务,例如:用户的相关操作就属于ums下的查询用户列表,查询用户积分,删除用户浏览记录,修改用户内容…
- 定义key之后增加value,第一个值属于业务组名第二个值开始属于controller
ums: ['ums', 'member/v2', 'grade/v2']
- 定义value在使用后controller不可在开头、中间存放一定要在末尾增加。删除一个controller,value的下标不可变,因为使用的是数组删除一个下标所有的value将重新指定下标
2.接口使用方式
//通过调用组名来获取想要的业务,在根据下标获取属于哪个controller的
this.mygetv2(this.param.ums[2] + "/list");//查询用户列表
this.myputv2(this.param.ums[1] + "/updateUserIntegral");//修改用户积分
3.代码
/**
* 组装url
* @param url 当前访问的url
* @returns {Object|*|string} 返回一个正确的url
*/
Vue.prototype.assembleURL = function (url) {
//根据URL分模块+controller请求
let urlArr = url.split('/');
const controller = urlArr[0] + '/' + urlArr[1];
url = this.blockurl(controller, url);
// console.log('assemble-' + controller);
return url;
}
/**
* 检查controller是哪个项目组
* url分为:项目名+版本+模块名(组名)+controller名+请求方法名...
* @param {Object} head 截取url第一个字段
* @param {Object} url 当前url
*/
Vue.prototype.blockurl = function (head, url) {
// console.log(head + '-----------------' + url)
//验证请求不用分组
if (head === '/oauth') {
return url;
}
//项目组
let group = [this.param.oms, this.param.ums];
for (let i = 0; i < group.length; i++) {
let res = this.checkURL(group[i], head, url);
if (res != null) return res;
}
//没有查到访问的是哪个url返回404
return '/404/' + url;
};
/**
- 检查一个url是否存在
- @param {Object} group
- @param {Object} controller
- @param {Object} url
*/
Vue.prototype.checkURL = function (group, controller, url) {
//有重复的controller但是项目组不一样,需要找到指定的项目组。通过@符来获取是属于哪个项目组
if (controller.indexOf('@') > -1) {
console.log('检测到重复的controller:' + controller.split('@'))
if (group[0] !== controller.split('@')[0]) {
return null;
}
return '/' + group[0] + "/" + url.split('@')[1];
}
if (group.indexOf(controller) > 0) {
return '/' + group[0] + "/" + url;
}
return null;
};
4.知识点
- assembleURL:把页面请求的url组装成正确的url
- blockurl:定义多个业务group,并做返回url容错处理
- checkURL:寻找controller和组装
5.优缺点
- 优点
- 减少代码修改量
- 约束接口定义规则
- 解决代码冗余
- 拓展性强
- 方便管理接口
- 缺点
- 使用接口的地方可读性差
- 数组下标不可变
总结
以上就是讲解封装axios带来的好处,强烈推荐遵守restful风格。对文章有疑问或者有指正的地方欢迎联系。
END