(六)Vue 网络通信—— Axios

  在 Vue 项目中,若想通过网络去请求一些数据,就需要使用 Axios 啦。

什么是 Axios?

  Axios 是一个开源的可以用在客户端和 NodeJS 的异步通信框架,它的主要作用就是实现 Ajax 异步通信,其功能特点如下:

  • 从浏览器中创建 XMLHttpRequests
  • 从 node.js 创建 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求数据和响应数据
  • 取消请求
  • 自动转换 JSON 数据
  • 客户端支持防御 XSRF(跨站请求伪造)

为什么使用 Axios?

  由于 Vue 是一个视图层框架且严格准守SoC(关注度分离原则),所以它并不包含 Ajax 的通信功能。
  为了解决通信问题,需要引入 Axios 框架。

Axios 框架的使用

基本使用

  Axios 和 Ajax 很像,下面为一个案例:

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
// 发送 POST 请求
axios({
method: 'post',
url: '/user/12345',
data: {
firstName: 'Fred',
lastName: 'Flintstone'
},
responseType:'stream'
});

// 为给定 ID 的 user 创建请求
axios.get('/user?ID=12345')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});

// 另一种指定参数的方式
axios.get('/user', {
params: {
ID: 12345
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
})
.then(function () {
// always executed
});


// 携带数据
axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});

  上面通过向 Axios 传递相关配置来创建请求,你应该可以很容易的看懂它们,其中:

  • method:请求方式,如 GET、POST、PUT
  • url:请求的 URL 路径
  • responseType:指定返回的类型;
  • then:数据成功返回时执行的函数,可以通过response.data取得数据;
  • catch:数据返回失败时执行的函数,可以通过error指定错误信息。

别名

  为方便起见,请求方法还提供了别名(部分):

  • axios.request(config)
  • axios.get(url[, config])
  • axios.post(url[, data[, config]])
  • axios.put(url[, data[, config]])

拦截器

  Axios 提供了拦截器,使得我们可以在以下操作过程中进行一些操作:

  • 请求成功时
  • 请求失败时
  • 响应成功时
  • 响应失败时

请求拦截

1
2
3
4
5
6
7
8
9
// config 为 axios 配置中的信息
axios.interceptors.request.use(config => {
// 请求成功时进行一些处理操作

return config;// 必须返回
}, err => {
// 请求失败时进行一些处理操作
console.log(err)
})

  请求成功时可以进行如下操作:

  • 过滤 config 中一些不符合服务器要求的信息
  • 每次发送网络请求时在在界面显示一个请求的图标(动画)
  • 监测 token 失效跳转到登录页要求用户重新登录

响应拦截(了解)

1
2
3
4
5
6
axios.interceptors.response.use(res => {
// return res
return res.data
}, err => {

})

Vue 中 Axios 的安装与使用

  首先执行如下命令安装:

1
npm install axios --save

  之后在需要的js文件导入即可使用:

1
import axios from 'axios'

低级使用

  对下面接口为http://127.0.0.1/user/query获取的 JSON 数据:

1
2
3
4
5
6
7
{
"id": 1,
"username": "jack",
"password": "123",
"name": "王五",
"telephone": 110
}

  现在通过 Axios 获取到 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
<div id="app">
{{info.id}}, {{info.username}}, {{info.password}}, {{info.name}}, {{info.telephone}}
</div>

<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
const vm = new Vue({
el: "#app",
data() {
return {
info: {
id: '',
username: '',
password: '',
name: '',
telephone: '',
}
}
},
created() {
axios({
method: 'get',
url: 'http://127.0.0.1/user/query',
})
.then(response => this.info = response.data);
}
});
</script>

  页面输出结果:

1
1, jack, 123, 王五, 110

高级使用

参数抽取

  从前面的栗子中,我们会发现一个问题:很多参数是固定的(如接口的请求地址)。
  在实际开发中,我们会一般利用 axios 的全局配置做一些抽取,:

1
2
3
4
5
6
// 基础 URL
axios.defaults.baseURL = 'http://www.lovike.cn/vue/api'
// 超时时间
axios.defaults.timeout = 50000
// 请求头
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'

  但是,有时候在同一项目中,由于服务器压力会设置多台,这时候使用全局的 URL 就不太合适了。
  这时候,我们可以创建多个 axios 实例来解决这个问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const first_instance = axios.create({
baseURL = 'http://www.lovike.cn/vue/api'
// 超时时间
timeout = 50000
})
const second_instance = axios.create({
baseURL = 'http://www.dreamsky.cn/vue/api'
// 超时时间
timeout = 40000
})

first_instance({
url: '/home'
}).then( res => {})

second_instance({
url: '/user/list',
params: {

}
}).then( res => {})

解耦

  考虑这样一个问题:若 axios 不维护了或出现重大 bug 啦,此时项目需要更换网络请求模块。
  你会发现,由于导入了太多的硬编码模块,需要全部修改,费时费力。
  那么,为什么不在一开始的时候就考虑好扩展性,编写工具类封装 axios,然后在需要使用的时候导入并使用该工具类呢?
  因此,我们可以在 vue 项目中创建一个专门的文件夹存放网络请求模块的文件utils,在其中编写工具类request.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import axios from 'axios'

export function request(config) {
return new Promise((resolve,reject) => {
// 创建 axios 实例
const instance = axios.create({
baseURL: 'http://lovike.cn/vue/api',
timeout: 5000
})

// 发送真正的网络请求
instance(config)
.then(res => {
resolve(res)
})
.catch(err => {
reject(err)
})
})
}

  其可以简写如下哦:

1
2
3
4
5
6
7
8
9
10
11
12
import axios from 'axios'

export function request(config) {
// 创建 axios 实例
const instance = axios.create({
baseURL: 'http://lovike.cn/vue/api',
timeout: 5000
})

// 发送真正的网络请求
return instance(config)
}

  其他地方这么导入使用就好了:

1
2
3
4
5
6
7
8
9
10
import {request} from './utils/request'

request({
method:
url: ''
}).then(res => {

}).catch(err => {

})

0%