在vue项目中,我们通常都是使用axios与后台进行数据交互,axios有很多好用的特性,这里不多做介绍,相关细节可以查阅axios中文网。在对axios进行封装之前,我们要使用vue脚手架工具创建一个vue项目(这里我用的是cli4)。
安装
1
2
|
cnpm install axios --save-dev; // 安装axios
cnpm install qs --save-dev; // 安装qs模块,用来序列化post类型的数据,否则后端无法接收到数据
|
模块引入
在src目录下创建一个service目录,用于存放接口封装的相关文件。然后在service目录中创建service.js,用于axios、qs模块的引入,并在此文件中对axios进行封装。代码如下(接口域名只有一个的情况):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
import axios from 'axios' //引入axios
import qs from 'qs' //引入qs,用来序列化post类型的数据,否则后端无法接收到数据
// 设置post请求头
axios.defaults.headers.post[ 'Content-Type' ] = 'application/x-www-form-urlencoded;charset=UTF-8' ;
axios.defaults.withCredentials = false ; //在跨域请求时,不会携带用户凭证;返回的 response 里也会忽略 cookie
//创建axios实例,请求超时时间为300秒
const instance = axios.create({
timeout: 300000,
});
//请求和响应拦截可以根据实际项目需求进行编写
// 请求发起前拦截
instance.interceptors.request.use((config) => {
//这里可以对接口请求头进行操作 如:config.headers['X-Token'] = token
console.log( "请求拦截" ,config);
return config;
}, (error) => {
// Do something with request error
return Promise.reject(error)
})
// 响应拦截(请求返回后拦截)
instance.interceptors.response.use(response => {
console.log( "响应拦截" ,response);
return response;
}, error => {
console.log( 'catch' , error)
return Promise.reject(error)
})
//按照请求类型对axios进行封装
const api={
get(url,data){
return instance.get(url,{params:data})
},
post(url,data){
return instance.post(url,qs.stringify(data))
},
}
export {api}
|
上述代码是接口域名只有一个的情况(多数情况),当接口域名有多个的时候(少数情况),我们需要对之前的封装进行改造,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
import axios from 'axios' //引入axios
import qs from 'qs' //引入qs,用来序列化post类型的数据,否则后端无法接收到数据
// 设置post请求头
axios.defaults.headers.post[ 'Content-Type' ] = 'application/x-www-form-urlencoded;charset=UTF-8' ;
axios.defaults.withCredentials = false ; //在跨域请求时,不会携带用户凭证;返回的 response 里也会忽略 cookie
//创建axios实例,请求超时时间为300秒,因为项目中有多个域名,所以对应的也要创建多个axios实例
const instanceA = axios.create({
timeout: 300000,
});
const instanceB = axios.create({
timeout: 300000,
});
//如果项目为单一域名,这里可以不用进行配置,当项目接口有多个域名时,要对axios实例基础路径进行配置,否则在项目生产环境中无法进行区别调用
if (process.env.NODE_ENV == 'production' ) {
instanceA.defaults.baseURL = 'https://www.production_a.com' ;
instanceB.defaults.baseURL = 'https://www.production_b.com' ;
}
//请求和响应拦截可以根据实际项目需求进行编写
// 请求发起前拦截
instanceA.interceptors.request.use((config) => {
//这里可以对接口请求头进行操作 如:config.headers['X-Token'] = token
console.log( "请求拦截" ,config);
return config;
}, (error) => {
// Do something with request error
return Promise.reject(error)
})
instanceB.interceptors.request.use((config) => {
console.log( "请求拦截" ,config);
return config;
}, (error) => {
// Do something with request error
return Promise.reject(error)
})
// 响应拦截(请求返回后拦截)
instanceA.interceptors.response.use(response => {
console.log( "响应拦截" ,response);
return response;
}, error => {
console.log( 'catch' , error)
return Promise.reject(error)
})
instanceB.interceptors.response.use(response => {
console.log( "响应拦截" ,response);
return response;
}, error => {
console.log( 'catch' , error)
return Promise.reject(error)
})
//按照请求类型对axios进行封装
const api={
get(url,data){
return instanceA.get(url,{params:data})
},
post(url,data){
return instanceA.post(url,qs.stringify(data))
},
doGet(url,data){
return instanceB.get(url,{params:data})
},
doPost(url,data){
return instanceB.post(url,qs.stringify(data))
}
}
export {api}
|
上述代码中有根据生产环境对axios实例的基础路径进行配置,如果项目中有多个环境(如:测试环境等),则需要对CLI4脚手架环境变量进行配置
api接口统一管理
将api接口按照功能模块进行拆分,把同一模块下的接口写在同一个文件中进行统一管理,这样代码会更容易维护。比如我们的项目中有新闻模块,音乐模块等。我们就在serviec目录中创建news.js、music.js文件,用于管理各自模块的所有api接口,这里我只拿news.js文件为例,代码如下:
1
2
3
4
5
6
7
8
9
10
|
import {api} from "./service.js" ;
const news={
getNewsList(){ //获取新闻列表
return api.get( "api/news/getNewsList" )
},
editNewsDetail(data){ //修改新闻详情
return api.post( "api/news/editNewsDetail" ,data);
}
}
export default news;
|
为了更方便在项目中调用这些封装好的接口,我们需要将这些接口挂载到vue的原型上,首先我们要在service目录中创建api.js文件,将所有模块的api管理文件引入进来,然后进行统一导出,代码如下:
1
2
3
4
5
6
|
//引入相关api管理模块
import news from "./news.js" ;
//进行统一导出
export default {
news
}
|
找到项目中的main.js文件,将接口挂载到vue的原型上,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import axios from 'axios'
Vue.prototype.axios=axios
Vue.config.productionTip = false
import api from "./service/api.js" ;
//将封装的接口挂载到vue原型上
Vue.prototype.$api = api;
new Vue({
router,
store,
render: h => h(App)
}).$mount( '#app' )
|
然后我们在项目创建完成时自动生成的模板文件App.vue调用封装好的接口,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
<template>
<div id= "app" >
<div id= "nav" >
<router-link to= "/" >Home</router-link> |
<router-link to= "/about" >About</router-link>
<button @click= "getN" >接口封装getN</button>
<button @click= "postN" >接口封装postN</button>
</div>
<router-view/>
</div>
</template>
<script>
export default {
methods:{
getN(){
this .$api.news.getNewsList().then((res)=>{
console.log(res);
})
},
postN(){
let openid= "oO5tQ5VMPpuzLqwfXhpmwjqwSANM" ;
let productCodes= "pro-1337270496655446016" ;
this .$api.news.editNewsDetail({openid,productCodes}).then((res)=>{
alert(res.data.msg);
})
}
}
}
</script>
<style lang= "scss" >
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
#nav {
padding: 30px;
a {
font-weight: bold;
color: #2c3e50;
&.router-link-exact-active {
color: #42b983;
}
}
}
</style>
|
配置代理
因为我们要在本地环境进行测试,这就涉及到了跨域问题,为了解决跨域问题,我们可以进行代理的配置,在项目根目录中创建vue.config.js文件,然后可以对项目进行各种配置,代理的配置方法如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
// vue.config.js
module.exports = {
// 输出文件目录
outputDir: "dist" ,
// eslint-loader 是否在保存的时候检查
lintOnSave: false ,
// 基本路径
publicPath: process.env.NODE_ENV === "production" ? "./" : "/" ,
devServer: {
host: "localhost" ,
port: 8080,
open: true ,
hotOnly: true , // 热更新
// 设置代理
proxy: {
"/api" : {
// 本地mock服务器
target: "https://www.xxxx.com/xxx/" ,
changeOrigin: true ,
ws: false ,
},
//如果项目中存在多个域名接口,可依次进行配置
"/apib" :{
target: "https://www.xxxx.com/xxx/" ,
changeOrigin: true ,
ws: false ,
},
},
},
};
|
代理配置好了之后,就可以运行项目了,命令行中输入npm run serve,项目启动好了之后,就可以进入页面点击按钮,测试之前做的封装是否好用。
结语
以上就是本人对vue中封装axios的一点心得,文章有错误或需要改进的地方还请与我联系,我将及时进行更正,感谢阅读。
以上就是vue中封装axios并实现api接口的统一管理的详细内容,更多关于vue 封装axios的资料请关注服务器之家其它相关文章!
原文链接:https://juejin.cn/post/6910020908837142536