03 在Vue项目中管理Axios请求和API接口

2019-06-17  本文已影响0人  酷炫派大星

目的

尝试封装Axios,并集中管理接口。目的是进一步提高项目的可维护性。

思路

  1. 确保项目中已经安装了Axios
  2. 在request.js文件中导入Axios,封装后导出给api.js;
  3. 在api.js文件中导入request.js中封装好的请求,定制接口,随后导出;
  4. 在页面中使用api.js暴露出的接口。

有思路了可以首先改造项目目录,在/src文件夹新建request文件夹,同时在此创建两个文件,分别是:

封装Axios请求

在request.js文件中导入axios
导入qs,暂时只知道这个是用来序列化字符串的库
有需要的话,导入轻提示UI组件 toast
导入vuex store因为拦截请求前,要验证里面的状态对象
导入路由,用于解决跳转

import axios from 'axios'
import QS from 'qs'
import { Toast } from 'vant'
import store from '@/store'
import router from '@/router'

环境配置

// 分别配置开发、调试、发布时请求的根地址
if (process.env.NODE_ENV === 'development') {
  axios.defaults.baseURL = ''
} else if (process.env.NODE_ENV === 'debug') {
  axios.defaults.baseURL = ''
} else if (process.env.NODE_ENV === 'production') {
  axios.defaults.baseURL = ''
}

请求的基本配置

// 设置链接超时时长
axios.defaults.timeout = 1000 * 5
// 设置post请求头
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'

请求的拦截

axios.interceptors.request.use(
  config => {
    // 请求前判断token是否存在,如果存在,再请求的header都加上token
    const token = store.state.token
    token && (config.headers.Authorization = token)
    return config
  },
  error => {
    return Promise.error(error)
  }
)

返回的拦截

axios.interceptors.response.use(
  response => {
    // 如果状态200,请求成功,否则抛出错误
    if (response.status === 200) {
      return Promise.resolve(response)
    } else {
      return Promise.reject(response)
    }
  },
  // 根据后台错误状态码进行操作
  // 以下是常规操作,其他需求自行拓展
  error => {
    if (error.response.status) {
      switch (error.response.status) {
        // 401 未登录
        case 401:
          // 跳转到登陆页面,并携带当前页面路径
          router.replace({
            path: '/login',
            query: {
              redirect: router.currentRoute.fullPath
            }
          })
          break
        // 403 token过期
        case 403:
          // 做出提示
          Toast({
            message: '403登陆信息异常,请重新登陆'
          })
          // 清除本地token
          localStorage.removeItem('token')
          // 清除vuex中的token对象
          store.commit('loginSucsess', null)
          // 1秒后,跳转到登陆页面,并携带当前页面路径
          setTimeout(() => {
            router.replace({
              path: '/login',
              query: {
                redirect: router.currentRoute.fullPath
              }
            })
          }, 1000)
          break
        // 404请求不存在
        case 404:
          Toast({
            message: '404请求不存在'
          })
          break
        default:
          // 提示信息
          Toast({
            message: error.response.data.message
          })
      }
      return Promise.reject(error.response)
    }
  }
)

封装并导出get方法

export function get (url, params) {
  return new Promise((resolve, reject) => {
    axios.get(url, {
      params: params
    })
      .then(res => {
        resolve(res.data)
      })
      .catch(err => {
        reject(err.data)
      })
  })
}

封装并导出post方法
这里有个问题要注意,axios.get()方法和axios.post()在提交数据时参数的书写方式还是有区别的。get的第二个参数是一个对象,这个对象的params属性值是参数对象。而post的第二个参数直接就是一个参数对象。

export function post (url, params) {
  return new Promise((resolve, reject) => {
    axios.post(url, params)
      .then(res => {
        resolve(res.data)
      })
      .catch(err => {
        reject(err.data)
      })
  })
}

API统一管理

在api.js文件中,导入request.js中封装好的get方法

import { get } from './request.js'

把接口暴露出去

// 如果有必要,把跟地址单独处理
const baseUrl = 'https://your_api_base_url.com'
// 定义接口,然后暴露出去
export const apiName = (params) => get(baseUrl + '/your_api_adress', params)

在需要使用接口的地方

// 导入接口
import { apiName } from '@/request/api.js'
// 使用接口
apiName(params)
    .then(res => {
       // 成功后的操作
    })
    .catch(res => {
       // 失败后的操作
    })
上一篇 下一篇

猜你喜欢

热点阅读