在vue项目中,和后台交互获取数据这块,我们通常使用的是axios库,它是基于promise的http库,可运行在浏览器端和node.js中。他有很多优秀的特性,例如拦截请求和响应、取消请求、转换json、客户端防御XSRF等。所以我们的尤大大也是果断放弃了对其官方库vue-resource的维护,直接推荐我们使用axios库。
Axios的中文文档:https://www.kancloud.cn/yunye/axios/234845
$ npm install axios -S
在项目的src目录中,新建一个request文件夹
,然后在里面新建一个http.js
和一个api.js
文件。http.js
文件用来封装我们的axios
,api.js
用来统一管理我们的接口。
// 在http.js中引入axios
import axios from 'axios'; // 引入axios
import QS from 'qs'; // 引入qs模块,用来序列化post类型的数据,后面会提到
安装qs
npm install qs -S
根据axios文档,新建一个实例:
var instance = axios.create({
baseURL: process.env.API_ROOT,
timeout: 30 * 1000
})
//
baseURL
将自动加在url
前面,除非url
是一个绝对 URL。
// 它可以通过设置一个baseURL
便于为 axios 实例的方法传递相对 URL
//
process.env.API_ROOT
是配置的不同环境的api,详情可看另一篇文章:Vue配置开发,测试,生产环境api
//
timeout
指定请求超时的毫秒数(0 表示无超时时间)
// 如果请求话费了超过timeout
的时间,请求将被中断
post请求的时候,我们需要加上一个请求头,所以可以在这里进行一个默认的设置,即设置post的请求头为application/x-www-form-urlencoded;charset=UTF-8
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
我们在发送请求前可以进行一个请求的拦截,进行一些我们想要的操作。
// 添加请求拦截器
instance.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
/* 添加loading S */
startLoading()
/* 添加loading E */
return config
}, function (error) {
// 对请求错误做些什么
/* 关闭loading S */
endLoading()
/* 关闭loading E */
return Promise.reject(error)
})
我们在请求响应后可以进行一个响应的拦截,进行一些我们想要的操作。
// 添加响应拦截器
instance.interceptors.response.use(function (response) {
// 对响应数据做点什么
/* 关闭loading S */
endLoading()
/* 关闭loading E */
return response
}, function (error) {
// 对响应错误做点什么
/* 关闭loading S */
endLoading()
/* 关闭loading E */
return Promise.reject(error)
})
我们常用的ajax
请求方法有get、post、put
等方法,相信小伙伴都不会陌生。axios
对应的也有很多类似的方法,不清楚的可以看下文档。但是为了简化我们的代码,我们还是要对其进行一个简单的封装。下面我们主要封装两个方法:get 和 post
。
get方法:我们通过定义一个get函数,get函数有两个参数,第一个参数表示我们要请求的url地址,第二个参数是我们要携带的请求参数。get函数返回一个promise对象,当axios其请求成功时resolve服务器返回
值,请求失败时reject错误值。
post方法:原理同get基本一样,但是要注意的是:
post方法必须要使用对提交从参数对象进行序列化的操作,所以这里我们通过 node 的 qs 模块来序列化我们的参数。这个很重要,如果没有序列化操作,后台是拿不到你提交的数据的。这就是文章开头我们 import QS from 'qs'; 的原因。
如果不明白序列化是什么意思的,就百度一下吧,答案一大堆。
var httpRequest = {
// get请求
get (url, params) {
return new Promise((resolve, reject) => {
instance({
method: 'get',
url: url,
params: params
}).then(response => {
// 请求成功
resolve(response.data)
}).catch(err => {
// 请求失败
console.log('请求失败')
reject(err)
})
})
},
// post请求
post (url, data) {
return new Promise((resolve, reject) => {
instance({
method: 'post',
url: url,
data: QS.stringify(data)
}).then(response => {
// 请求成功
resolve(response.data)
}).catch(err => {
// 请求失败
console.log('请求失败')
reject(err)
})
})
}
}
export default httpRequest
我们使用字面量方法封装好get
和post
方法后,使用export default
导出方法
上面说了,我们在api.js
中统一管理我们的接口
1、首先,我们在api.js
中引入封装的axios
,即http.js
import httpRequest from './http'
2、然后,例如我们有一个接口,是一个post请求
:
https://baidu.com/User/Login
我们可以在api.js
中这样封装:
export default {
// 接口 登录
postLogin: p => httpRequest.post('https://baidu.com/User/Login', p)
// 其他接口 xxx
}
其他的api接口,就在api.js中继续往下面扩展就可以了。tips:代码千万行,注释第一行,请为每个接口写好注释!!!
3、接下来,我们在main.js
里面引用api.js
,并把它挂到Vue的原型上
import api from './request/api'
Vue.prototype.$api = api
4、最后,在组件里面调用接口如下:
methods: {
// 请求 登录接口
postLogin() {
this.$api.postLogin({account: '', password: ''}).then(response => {
console.log(response)
}).catch(error => {
console.log(error.response)
})
}
},
最后的最后,把完成的axios封装代码、接口管理代码
奉上
/***
* axios封装代码
***/
import Vue from 'vue'
import axios from 'axios'
import QS from 'qs'
var instance = axios.create({
baseURL: process.env.API_ROOT,
timeout: 30 * 1000
})
instance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'
// 添加请求拦截器
instance.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
/* 添加loading S */
startLoading()
/* 添加loading E */
return config
}, function (error) {
// 对请求错误做些什么
/* 关闭loading S */
endLoading()
/* 关闭loading E */
return Promise.reject(error)
})
// 添加响应拦截器
instance.interceptors.response.use(function (response) {
// 对响应数据做点什么
/* 关闭loading S */
endLoading()
/* 关闭loading E */
return response
}, function (error) {
// 对响应错误做点什么
/* 关闭loading S */
endLoading()
/* 关闭loading E */
return Promise.reject(error)
})
var httpRequest = {
// get请求
get (url, params) {
return new Promise((resolve, reject) => {
instance({
method: 'get',
url: url,
params: params
}).then(response => {
// 请求成功
resolve(response.data)
}).catch(err => {
// 请求失败
console.log('请求失败')
reject(err)
})
})
},
// post请求
post (url, data) {
return new Promise((resolve, reject) => {
instance({
method: 'post',
url: url,
data: QS.stringify(data)
}).then(response => {
// 请求成功
resolve(response.data)
}).catch(err => {
// 请求失败
console.log('请求失败')
reject(err)
})
})
}
}
export default httpRequest
/***
* 接口管理代码
***/
import httpRequest from './http'
export default {
// 接口 登录
postLogin: p => httpRequest.post('https://baidu.com/User/Login', p)
// 其他接口 xxx
}
谢谢阅读本篇文章