# 接口交互
## 请求发起的流程
由于Vue作者的号召，Vue项目基本上无一例外的采用了axios库来进行接口交互，发起模式一般有以下两种： 
```txt
1. UI 组件交互操作
2、调用统一管理的 api 请求函数
3、使用封装的request.js发送请求
4、获取服务端返回
5、更新视图或者其他操作  
``` 
或者
```txt
1、UI 组件交互操作
2、调用Vuex的action
3、调用统一管理的 api 请求函数
4、使用封装的request.js发送请求
5、获取服务端返回
6、更新State
7、state触发更新视图或做他用
``` 
一般情况下，我们推荐使用第一种方式，此处也以第一种情况作为案例来说明，如果你要使用第二种结合vuex使用，在action中引入即可。

从上面的流程可以看出，为了方便管理维护，统一的请求处理都放在 @/src/api 文件夹中，并且一般按照 model 维度进行拆分文件，如：
```
api/
  index.js
  model1.js
  model2.js
  ...
```
index.js中包含了所有模块的加载器，你只需要直接添加模块即可  

一个模块的结构是这样的
```javascript
import request from '../utils/request'

export default {
  // 在Vue组件中调用时使用this.$api.getCpus
  getCpus: data => {
    return request({
      data,
      url: '/mock/api/cpu',
      method: 'post'
    })
  }
}
```

:::warning 注意
这里需要提示一下，由于最后所有的请求api都会合并到this.$api下，所有在命名时需要避免重名，否则将会有api被覆盖的风险。
:::

## request.js
其中，../utils/request.js 是基于 axios 的封装，便于统一处理 POST，GET 等请求参数，请求头，以及错误提示信息等。具体可以参看 request.js。 它封装了全局 request拦截器、response拦截器、统一的错误处理、统一做了超时处理、baseURL设置等。

## 一个发起请求的例子
```javascript
// api/demo.js
import request from '../utils/request'

export default {
  getCpus: data => {
    return request({
      data,
      url: '/mock/api/cpu',
      method: 'post'
    })
  }
}
// 在

export default {
  data() {
    cpusInfo: {},
    fetchLoading: false
  },
  methods: {
    async getCpus() {
      try {
        this.fetchLoading = true
        this.cpusInfo = await this.$api.getCpus()
      } catch (e) {
        console.log(e)
      } finally {
        this.fetchLoading = false
      }
    }
  }
}
```
[comment]: <> ( TODO 后面应该也会会支持多个baseUrl)
## 根据不同的环境变量设置 baseURL
这个在此前的章节中有提到：[根据不同的环境变量设置 baseURL](/项目构建/环境变量.html#通过环境变量控制访问不用的url)
```javascript
// utils/request.js
import axios from 'axios'

import baseUrl from '../config/baseUrl.js'

axios.defaults.headers.common['Content-Type'] = 'application/json;charset=UTF-8'

axios.defaults.baseURL = baseUrl.api // 发送请求的基础url

axios.defaults.timeout = 5000 // 请求的超时时间
```

