vue入门–基础命令+axios+案例练习
vue入门–vue常用属性、生命周期、计算属性、过滤器、组件、虚拟DOM、数组的响应式方法、页面闪烁、ES6简单语法增强
vue入门–js高阶函数(箭头函数)、v-model数据绑定、组件化、父子组件通信及访问
vue入门–插槽(具名、匿名、作用域插槽)+ES6模块化导入导出+webpack的使用(基本使用+配置使用+如何一步步演化成cli脚手架)+webpack插件使用(搭建本地服务器、配置文件分离)
vue-cli脚手架2版本及3+版本安装、目录解析、only和compiler的区别、3+版本如何改配置、箭头函数及this的指向
vue-router基本使用、路由传参、懒加载、嵌套路由、导航守卫、keep-alive
Promise基本使用、三种状态、链式调用及简写、all方法
Vuex的作用、使用、核心概念(State、Mutations、Getters、Actions、Modules)、文件抽离
axios网络请求基本使用、配置使用(全局axios和局部axios实例)、模块封装、axios拦截器

网络模块封装

Vue中发送网络请求的方式很多,如何选择?

  • 原生Ajax : 基于XMLHttpRequest,好解释,但是配置和调用方式混乱,编码看起来头疼
  • jquery-ajax : 经常使用,但是在Vue中已经不再是使用Jquery了,没必要再为了ajax引入jquery,而且jquery也是重量级的
  • axios: 用起来方便,支持多功能:在nodejs中发送http请求,支持Promise,拦截请求和响应、转换请求和响应等

axios基本使用

支持多种请求方式:

安装axios框架

npm install axios --save

引入

import axios from 'axios'

普通使用

axios(config),config就是发送请求的一些配置,比如请求方式(默认是GET请求)

B站教程-why老师的教程,还提供了相关的接口数据,可参考。

axios.config({url: 'http://xxx.xxx.xxx/home/multidata'}).then(res => {console.log(res)})

查看返回数据

返回的是一个object对象,然后内部由config、data(返回的数据)、headers等数据

在不设置请求方式时,默认就是Get方式请求,我们也可以在config中指定请求的方式:

axios.config({url: 'http://xxx.xxx.xxx/home/multidata',method: 'GET'}).then(res => {console.log(res)})

Get请求

axios.get()

get(url: string, config" />: AxiosRequestConfig<any> | undefined): Promise<AxiosResponse<any, any>>

需要两个参数,一个请求的url,还有一个请求的config信息,config不是必填的

axios.get('http://xxx.xxx.xxx/home/multidata').then(res => {console.log(res)})

假如有参数,如 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)})

直接在接收的第二个参数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])})

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)}))

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)})

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)})

封装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)})}

    调用者如何使用呢?

    以App.vue组件为例,在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>

  • (思路理清) 使用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)})})}

    调用者调用

    created() {req({url: '/home/multidata'}).then(res => {this.result = res}).catch(err =>{console.log(err)})}
  • 最终方案(使用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)}

    调用

    created() {req({url: '/home/multidata'}).then(res => {this.result = res}).catch(err =>{console.log(err)})}

axios拦截器

axios提供了拦截器,用于我们在每次发送请求或者得到结果后,进行响应的处理。可使用4中机制的拦截:

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

如何使用” />// 全局的axios.interceptors// 单个实例的axios实例.interceptors

请求拦截

以我们上面封装的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)}

看控制台信息

可以看到发送请求前,拦截到了并且获取到了信息,有baseURL,headers等等,但是下面有个报错,为啥呢?

注意看下面的代码,我们对request进行了拦截,并且获取到了信息,但是我们没有把 信息重新给 return 回去,那么这个请求的config信息都获取不到了,直接报错了,我们必须要return 回去信息.

instance.interceptors.request.use(config => {console.log(config)}, err => {console.log(err)})

正确做法:

instance.interceptors.request.use(config => {console.log(config)return config}, err => {console.log(err)})

那么拦截器有什么作用呢?

  • 假如有某个需求,每次发送请求时都要去对headers中的一些信息进行校验或者更改,我们就需要使用到拦截器,然后对拦截到的信息做一些更改,再return 给这个 请求。

    instance.interceptors.request.use(config => {console.log(config)config.headers = {xxx: 'xxx'}return config}, err => {console.log(err)})
  • 每次发送请求时,让页面上显示一个加载的小动画,当请求成功后,再给他隐藏掉

    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)}
  • 某些网络请求,必须携带一个特殊信息,比如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)}

响应拦截

和请求拦截类似,不过拦截的机制不同,响应拦截是发送网络请求后,进行的拦截

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)}

一般情况下,我们只需要拿到响应的data就行了。

和请求拦截一样,需要注意的是:拦截到数据后,一定要 将返回的信息 return 给接收者,否则接收者获取到的数据都是 undefind,需要什么返回什么就行,如只需要响应的数据,那就把data给返回即可

instance.interceptors.response.use(result => {console.log(result)return result.data}, err => {console.log(err)})
vue入门–基础命令+axios+案例练习
vue入门–vue常用属性、生命周期、计算属性、过滤器、组件、虚拟DOM、数组的响应式方法、页面闪烁、ES6简单语法增强
vue入门–js高阶函数(箭头函数)、v-model数据绑定、组件化、父子组件通信及访问
vue入门–插槽(具名、匿名、作用域插槽)+ES6模块化导入导出+webpack的使用(基本使用+配置使用+如何一步步演化成cli脚手架)+webpack插件使用(搭建本地服务器、配置文件分离)
vue-cli脚手架2版本及3+版本安装、目录解析、only和compiler的区别、3+版本如何改配置、箭头函数及this的指向
vue-router基本使用、路由传参、懒加载、嵌套路由、导航守卫、keep-alive
Promise基本使用、三种状态、链式调用及简写、all方法
Vuex的作用、使用、核心概念(State、Mutations、Getters、Actions、Modules)、文件抽离
axios网络请求基本使用、配置使用(全局axios和局部axios实例)、模块封装、axios拦截器