「这是我参与2022首次更文挑战的第4天,活动详情查看:2022首次更文挑战」
前言
在项目中网络请求模块是前后端沟通的基础,接下来我们就在Vue项目中使用Axios实现最基本的网络请求模块吧。
项目背景
- Vue2
- Vue-axios
- axios
PS:axios是一个库,它不是一个vue的第三方插件,所以无法像其他第三方插件一样直接使用Vue.use()来安装。
为了更方便使用我们引入vue-axios(www.npmjs.com/package/vue…) ,作者介绍说vue-axios是将axios集成到Vue.js的小包装器,可以把axios像插件一样进行安装。
安装
npm install --save axios vue-axios
使用
import Vue from 'vue'
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)
操作步骤
1.确定结构
在src目录下创建一个service的文件夹封装的通用网络请求的js代码写在下面
interceptors.service.js:axios拦截器 用来添加发送请求前和接收数据后需要做的事情。api.service.js:用来封装不同类型请求的公共方法。
在src目录下创建一个apis的文件夹
- 创建不同功能模块对应的api文件
2.拦截器 interceptors.service.js
利用Axios的拦截器方法interceptor.interceptors.request.use() 在 发送request请求 之前做了一些配置:
- 传入用户的token,发送给后端进行身份识别
- 传入用户当前选择的语言,让后端可以根据当前语言输出相应的资料
- 设置发出请求的loading动画
当然你也可以根据项目的具体需求做一些更详细的配置
import axios from "axios";
const interceptor = axios.create();
interceptor.interceptors.request.use(
function(config) {
//设置headers传入用户的token
if (localStorage.id_token) {
config.headers.Authorization = "Bearer " + localStorage.id_token;
}
//设置headers头传入当前使用的语言,提供给后端判断用。
config.headers["Accept-Language"] = i18n.locale;
//这边可以使用一些loading的动画,请求的时候loading动画运转,请求完成或者错误之后动画关闭
//(这里用的是element-ui 的loading组件)
loadingInstance = Loading.service({
lock: true,
background: "transparent"
});
return config;
},
function(error) {
// 请求错误,关闭loading动画,返回错误。
loadingInstance.close();
return Promise.reject(error);
}
);
* (ps:我这边传入当前语言是用的 vue-i18n 套件,想了解的可以看我这篇文章 Vue2项目中前端国际化处理 vue-i18n + element)
利用Axios的拦截器方法interceptor.interceptors.response.use 对 接收的response响应 进行判断和操作的处理
- 请求成功,关闭loading动画 ,返回数据
- 请求失败,关闭loading动画,和后端同学约定规则,抓取错误码,针对错误码进行判断和自定义错误之后如何处理。
常用的错误处理是页面alert错误信息,页面跳转。
常见错误码:400-请求无效,404-无法找到网页,403-服务器端禁止访问,等等
interceptor.interceptors.response.use(
//成功返回数据
function(response) {
//关闭loading动画
loadingInstance.close();
//返回数据待使用
return response.data;
},
//抓取数据,针对不同的错误进行不同的操作
function(error) {
//和后端小伙伴约定一下错误码的规则
if (error.response.status === 400) {
switch (error.response.data.message) {
case "Not found user":
case "Unauthorized":
// do nothing.
break;
case "Blocked":
router.push({ path: "/inactive" });
break;
default:
//页面输出错误讯息(element-ui)
Message.error("Oop, something went wrong. Please contact us.");
}
}
if (error.response.status === 403) {
//页面输出错误讯息(element-ui)
Message.error(error.response.data.message);
}
if (error.response.status === 404) {
//跳转404页面
router.push({
name: "404"
});
}
//关闭loading动画
loadingInstance.close();
return Promise.reject(error);
}
);
最后导出模块
export default interceptor;
3.封装公共方法API api.service.js
常用的方法
get(resource, slug = "", params):用于获取数据;post(resource, params, config):用于提交数据(新建),表单提交和文件上传等patch(resource, params, config),put(resource, params, slug = ""):用于更新数据(修改);delete(resource, params, config):用于删除数据;
import Vue from "vue";
//引入刚刚的配置好的axios拦截器
import axios from "@/service/interceptors.service";
import VueAxios from "vue-axios";
const ApiService = {
//初始化方法用vue-axios组件
init() {
Vue.use(VueAxios, axios);
//设置api的baseURL
Vue.axios.defaults.baseURL = "https://www.qq.com/api/";
},
//创建不同的网络请求方法
get(resource, slug = "", params) {
return Vue.axios.get(`${resource}/${slug}`, { params }).catch(error => {
throw error.response;
});
},
query(resource, params) {
return Vue.axios.get(resource, { params }).catch(error => {
throw error.response;
});
},
post(resource, params, config) {
return Vue.axios.post(`${resource}`, params, config).catch(error => {
throw error.response;
});
},
patch(resource, params, slug = "") {
return Vue.axios.patch(`${resource}/${slug}`, params).catch(error => {
throw error.response;
});
},
put(resource, params, slug = "") {
return Vue.axios.put(`${resource}/${slug}`, params).catch(error => {
throw error.response;
});
},
delete(resource, params, slug = "") {
return Vue.axios
.delete(`${resource}/${slug}`, { data: params })
.catch(error => {
throw error.response;
});
}
};
export default ApiService;
4. main.js引入封装好的网络请求模块
想要正常的使用,需要将封装好的网络请求模块引入
//main.js
import ApiService from "@/service/api.service";
ApiService.init();
5.根据不同功能模块的创建各自的API方法文件
比如关于学生的功能模块就创建一个@/apis/students.js,老师的功能模块就创建一个@/apis/teachers.js。
引入api.service网络请求,新增api方法
*src/apis/students.js*
import ApiService from "@/common/api.service";
export default {
getStudents() {
return ApiService.query("students");
}
}
将每个功能模块都单独创建一个api文件,编写只属于这个模块的api方法。
这样做的好处是: 小伙伴们看到这个api的文件名字就能很好的理解这个api是服务于哪一个功能模块的,更加方便小伙伴快速上手,减少沟通成本。如果之后某个模块的api需要调整的话可以快速定位对应的api文件,修改起来也很方便。
6.在组件中使用
引入该功能模块对应的api文件,在需要和后端对接的时候,调用api方法与后端做沟通。
*students.vue*
import StudentsApi from "@/apis/students.js";
export default {
data() {
return {
students: null
};
},
computed: {},
watch: {},
async mounted() {
this.students = await StudentsApi.getStudents();
},
methods: {}
};
</script>
小结
以上就是我在项目中使用的网络请求模块的封装全部操作,希望可以给大家带来帮助Thanks♪(・ω・)ノ。