企业管理系统定制开发网络模块封装
Vue企业管理系统定制开发中发送网络请求的方式很多,如何选择?
- 原生Ajax : 基于XMLHttpRequest,好解释,企业管理系统定制开发但是配置和调用方式混乱,企业管理系统定制开发编码看起来头疼
- jquery-ajax : 经常使用,但是在Vue企业管理系统定制开发中已经不再是使用Jquery了,企业管理系统定制开发没必要再为了ajax引入jquery,而且jquery企业管理系统定制开发也是重量级的
axios
: 企业管理系统定制开发用起来方便,支持多功能:在nodejs中发送http请求,支持Promise,拦截请求和响应、转换请求和响应等
axios基本使用
支持多种请求方式:
框架
npm install axios --save
- 1
引入
import axios from 'axios'
- 1
普通使用
axios(config)
,config就是发送请求的一些配置,比如请求方式(默认是GET
请求)
,还提供了相关的接口数据,可参考。
axios.config({ url: 'http://xxx.xxx.xxx/home/multidata'}).then(res => { console.log(res)})
- 1
- 2
- 3
- 4
- 5
查看返回数据
返回的是一个object对象,然后内部由config、data(返回的数据)、headers等数据
在不设置请求方式时,默认就是Get方式请求,我们也可以在config中指定请求的方式:
axios.config({ url: 'http://xxx.xxx.xxx/home/multidata', method: 'GET'}).then(res => { console.log(res)})
- 1
- 2
- 3
- 4
- 5
- 6
Get请求
axios.get()
get(url: string, config?: AxiosRequestConfig<any> | undefined): Promise<AxiosResponse<any, any>>
- 1
需要两个参数,一个请求的url,还有一个请求的config信息,config不是必填的
axios.get('http://xxx.xxx.xxx/home/multidata').then(res => { console.log(res)})
- 1
- 2
- 3
- 4
假如有参数,如 http://xxx.xxx.xxx/base/list?type=a&page=1
,怎么传递呢
axios.get('http://xxx.xxx.xxx/home/data',{ params:{ type: 'pop', page: 1 }}).then(res => { console.log(res)})
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
直接在接收的第二个参数config对象中定义 params
即可。最后请求时会自动把这些参数通过问号拼接在请求的url上面。
发送并发请求
使用axios的all()方法,接收一个数组参数
axios.all([ axios({ url: 'http://xxx.xxx.xxx.xxx/home/multidata' }), axios({ url: 'http://xxx.xxx.xxx.xxx/home/data', params:{ type: 'aaa', page: 2 } })]).then(results => { console.log(results[0]) console.log(results[1])})
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
all()方法中定义了两个axios的网络请求,当两个网络请求(异步操作)完毕后,进入到then()方法中处理数据。
then()
中results是获取的两个结果加在一起的数组对象,太麻烦了,能否单独获取到这两个请求各自的得到的结果呢?
axios提供了一个spread的方法,可以将数组 [res1,res2]展开为 res1, res2
axios.all([ axios({ url: 'http://xxx.xxx.xxx.xxx/home/multidata' }), axios({ url: 'http://xxx.xxx.xxx.xxx/home/data', params:{ type: 'aaa', page: 2 } })]).then(axios.spread((res1, res2) => { console.log(res1) console.log(res2)}))
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
axios配置
全局配置
事实上,在开发中可能很多的参数都是固定的,这个时候我们可以进行一些抽取,也可以利用axios的全局配置
设置后全局性生效,如请求的地址会变成 baseURL+url
的拼接值,请求的超时时间为5s,超时后报错
axios.defaults.baseURL = 'http://xxx.xxx.xxx.xxx'// 单位是毫秒axios.defaults.timeout = 5000axios({ url: '/home/multidata'}).then(res =>{ console.log(res)})
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
axios常见的配置选项
- url : 请求地址
- method : 请求类型
- baseURL : 请求根路径
- transformRequest : 请求前的数据处理
- transformResponse : 请求后的数据处理
- headers : 自定义请求头
params : URL数据拼接
适用于GET请求data : request body(请求体,一般放数据)
适用于POST请求- responseType: ‘json’,响应的数据格式
axios实例和模块封装
使用axios实例
前面我们都是使用的全局的axios对象。而开发中,假如有多个服务器,那么使用全局的axios配置的话实现起来也比较麻烦。我们可以创建axios(局部)的实例。
// 创建一个axios的局部实例,并且设置好了配置const in1 = axios.create({ baseURL: 'http://xxx.xxx.xxx.xxx', timeout: 5000})// 使用axios实例in1({ url: '/home/multidata'}).then(res => { console.log(res)})// 使用axios实例in1({ url: '/home/data', params:{ type: 'pop', page: 1 }}).then(res => { console.log(res)})
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
封装axios
开发中,不要每个组件都使用import axios form 'axios'
的方式,代码复用性太差,而且后期如果更换组件,维护起来过于麻烦。我们可以封装到一个文件中,然后其他组件直接可以使用即可。
如何封装?
可以在src
下创建一个network
的目录,涉及到网络相关的东西,都放入到这个目录中。
封装一个request组件,考虑一个问题,因为封装好的request,其他模块都要去调用,所以我们网络请求获取到数据后的处理应该去交给调用者来处理,而不是在request组件中处理。
要实现也有很多的方式:
-
调用封装好request时,需要我们传入一个success和fail的回调(
了解即可
)封装一个request
import axios from 'axios'export function req(config, success, fail) { const instance = axios.create({ baseURL: 'http://xxx.xxx.xxx.xxx', timeout: 5000 }) // 使用axios的实例,并且调用响应的 回调 instance(config) .then(res => { success(res); }).catch(err => { fail(err) })}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
调用者如何使用呢?
以App.为例,在App组件创建完毕后进行网络请求数据,然后回显
<template> <div id="app"> <p>{{result}}</p> </div></template><script>import { req } from './network/request'export default { name: 'App', data() { return { result: '' } }, created() { req({ url: '/home/multidata' // 请求地址 },succ =>{ // 处理成功回调 this.result = succ },err => { // 失败回调 console.log(err) }) }}</script><style></style>
- 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
-
(
思路理清
) 使用Promise封装request
import axios from 'axios'export function req(config) { return new Promise((resolve, reject) => { const instance = axios.create({ baseURL: 'http://xxx.xxx.xxx.xxx', timeout: 5000 }) // 使用axios实例 instance(config).then(res => { // 成功时 resolve(res) }).catch(err => { // 失败时 reject(err) }) })}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
调用者调用
created() { req({ url: '/home/multidata' }).then(res => { this.result = res }).catch(err =>{ console.log(err) })}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-
最终方案(使用Promise)
上面的方案其实就是给返回一个Promise的实例,方便调用者实现回调,但是其实创建axios的实例后,调用axios实例时返回值是一个
Promise
的类型,所以我们直接return这个axios的调用就行了.import axios from 'axios'export function req(config) { const instance = axios.create({ baseURL: 'http://xxx.xxx.xxx.xxx', timeout: 5000 }) return instance(config)}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
调用
created() { req({ url: '/home/multidata' }).then(res => { this.result = res }).catch(err =>{ console.log(err) })}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
axios拦截器
axios提供了拦截器,用于我们在每次发送请求或者得到结果后,进行响应的处理。可使用4中机制的拦截:
- 请求成功
- 请求失败
- 响应成功
- 响应失败
如何使用?
// 全局的axios.interceptors// 单个实例的axios实例.interceptors
- 1
- 2
- 3
- 4
- 5
请求拦截
以我们上面封装的request组件为例
import axios from 'axios'export function req(config) { const instance = axios.create({ baseURL: 'http://xxx.xxx.xxx.xxx', timeout: 5000 }) instance.interceptors.request.use(config => { console.log(config) }, err => { console.log(err) }) return instance(config)}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
看控制台信息
可以看到发送请求前,拦截到了并且获取到了信息,有baseURL,headers等等,但是下面有个报错,为啥呢?
注意看下面的代码,我们对request进行了拦截,并且获取到了信息,但是我们没有把 信息重新给 return 回去,那么这个请求的config信息都获取不到了,直接报错了,我们必须要return 回去信息.
instance.interceptors.request.use(config => { console.log(config)}, err => { console.log(err)})
- 1
- 2
- 3
- 4
- 5
正确做法:
instance.interceptors.request.use(config => { console.log(config) return config}, err => { console.log(err)})
- 1
- 2
- 3
- 4
- 5
- 6
那么拦截器有什么作用呢?
-
假如有某个需求,每次发送请求时都要去对headers中的一些信息进行校验或者更改,我们就需要使用到拦截器,然后对拦截到的信息做一些更改,再return 给这个 请求。
instance.interceptors.request.use(config => { console.log(config) config.headers = { xxx: 'xxx' } return config}, err => { console.log(err)})
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-
每次发送请求时,让页面上显示一个加载的小动画,当请求成功后,再给他隐藏掉
import axios from 'axios'export function req(config) { const instance = axios.create({ baseURL: 'http://xxx.xxx.xxx.xxx', timeout: 5000 }) instance.interceptors.request.use(config => { console.log(config) // 展示加载的动画 return config }, err => { console.log(err) }) // 执行到这里,隐藏动画 return instance(config)}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
-
某些网络请求,必须携带一个特殊信息,比如token
import axios from 'axios'export function req(config) { const instance = axios.create({ baseURL: 'http://xxx.xxx.xxx.xxx', timeout: 5000 }) instance.interceptors.request.use(config => { console.log(config) if(config.headers.token == null) { // 告诉用户先登录 (处理) } return config }, err => { console.log(err) }) return instance(config)}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
响应拦截
和请求拦截类似,不过拦截的机制不同,响应拦截是发送网络请求后,进行的拦截
import axios from 'axios'export function req(config) { const instance = axios.create({ baseURL: 'http://xxx.xxx.xxx.xxx', timeout: 5000 }) instance.interceptors.response.use(result => { console.log(result) return result }, err => { console.log(err) }) return instance(config)}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
一般情况下,我们只需要拿到响应的data就行了。
和请求拦截一样,需要注意的是:拦截到数据后,一定要 将返回的信息 return 给接收者,否则接收者获取到的数据都是 undefind
,需要什么返回什么就行,如只需要响应的数据,那就把data给返回即可
instance.interceptors.response.use(result => { console.log(result) return result.data}, err => { console.log(err)})
- 1
- 2
- 3
- 4
- 5
- 6