Vue关于axios的封装调用

在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文件用来封装我们的axiosapi.js用来统一管理我们的接口。
Vue关于axios的封装调用_第1张图片

// 在http.js中引入axios
import axios from 'axios'; // 引入axios
import QS from 'qs'; // 引入qs模块,用来序列化post类型的数据,后面会提到

安装qs

npm install qs -S

使用自定义配置新建一个 axios 实例

根据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请求的时候,我们需要加上一个请求头,所以可以在这里进行一个默认的设置,即设置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)
})

封装get方法和post方法

我们常用的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

我们使用字面量方法封装好getpost方法后,使用export default导出方法

axios的封装基本就完成了,下面说下api的统一管理

上面说了,我们在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封装代码、接口管理代码奉上

  • http.js代码
/***
* 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

  • api.js代码
/***
* 接口管理代码
***/
import httpRequest from './http'
export default {
  // 接口 登录
  postLogin: p => httpRequest.post('https://baidu.com/User/Login', p)
  
  // 其他接口 xxx
  
}

谢谢阅读本篇文章

你可能感兴趣的:(Vue.js)