Vue工程中单独封装axios拦截器

  之前项目的axios数据请求基本都是写在各组件方法内,如项目接口变动要修改url地址等参数会比较为麻烦,不易维护,决定对axios进行封装并将接口统一管理。

一、新建函数文件:

  在vue-cli工程内新建axios-request.js、axios-api.js,其中aixos-request.js用于对axios进行封装,axios-api.js用于接口的统一管理,两个的文件位置根据自身的工程目录来定,我的是存放在src文件夹下的axios文件夹内。

二、对axios进行封装:

// axios-request.js
import Vue from 'vue'
import Toast from 'muse-ui-toast' /* 引入muse-ui的Toast插件 */
import axios from 'axios'
import qs from 'qs' /* 引入qs依赖包,对传参数据序列化 */
Vue.use(Toast, {
  time: 5000 /* 设置Toast显示5s,防止用户没有注意到 */
})

/* 创建axios实例 */
const axiosService = axios.create({
  baseURL: process.env.API_HOST, /* 在config/dev.evn.js、prod.evn.js里面进行配置 */
  timeout: 5000 /* 设置超时时间为5s */
})

/* request拦截器 ==> 对请求参数进行处理 */
axiosService.interceptors.request.use(
  config => {
    config.method === 'post'
      ? config.data = qs.stringify({...config.data})
      : config.params = {...config.params}
      /* 判断method是否为post,为post则对参数进行序列化,不为post择不进行序列化 */
    config.headers['Content-Type'] = 'application/x-www-form-urlencoded'
    return config
  }, error => {
    Toast.error('错误,请重新操作...')
    Promise.reject(error)
  })

/* respone拦截器 ==> 对响应做处理 */
axiosService.interceptors.response.use(
  response => {
    if (response.data) {
      return response.data
    } else {
      Toast.error('数据错误,请重试...')
    }
  }, error => {
    /* 判断error的status代码,并将对应的信息告知用户 */
    let text = ''
    let err = JSON.parse(JSON.stringify(error))
    if (err.response.status) {
      switch (error.response.status) {
        case 400:
          text = '请求错误(400),请重新申请'
          break
        case 401:
          text = '登录错误(401),请重新登录'
          return this.$router.replace('/Login')
        case 403:
          text = '拒绝访问(403)'
          break
        case 404:
          text = '请求出错(404)'
          break
        case 408:
          text = '请求超时(408)'
          break
        case 500:
          text = '服务器错误(500),请重启软件或切换功能页!'
          break
        case 501:
          text = '服务未实现(501)'
          break
        case 502:
          text = '网络错误(502)'
          break
        case 503:
          text = '服务不可用(503)'
          break
        case 504:
          text = '网络超时(504)'
          break
        case 505:
          text = 'HTTP版本不受支持(505)'
          break
        default:
          text = '网络连接出错'
      }
    } else {
      text = '连接服务器失败,请退出重试!'
    }
    Toast.error(text)
    return Promise.reject(error)
  }
)

/* 将写好的axios实例暴露出去 */
export default axiosService

  这里使用了muse-uiToast插件用于用户提示。

  如果后台需要前端发送时携带token,应在axiosService.interceptors.request.use的config内增加相关内容,我的项目中没有运用到token,简单的形式参考下面的代码:

1 if (store.state.token) {  // 判断是否存在token,如果存在的话,则每个http header都加上token
2             config.headers.Authorization = `token ${store.state.token}`;
3         }

三、对接口进行统一管理:

// axios-api.js
import axiosService from './axios-request' /* 从axios-request.js内引入axiosService */
 
/* 下面是POST形式 */
export const userLogin = data => {
  return axiosService({
    url: '/XXXX/user/xxxx', /* 根据实际接口地址来写 */
    method: 'post',
    data
  })
}

/* 下面是GET形式 */
export const userInfo = params=> {
  return axiosService({
     url: '/XXXX/user/XXXXX.action',
     method: 'get',
     params
  })
}

  这里要注意下,post参数放在data内,get参数放在params内

四、在组件内使用写好的接口:

下面是根据我的工程写的一个登录接口,仅供参考:

 1 import { userLogin } from '../../axios/axios-api' /* 引入登录接口函数 */
 2 methods: {
 3     async login () {
 4       this.loginLoading = true
 5       let userName = this.userName
 6       let passWord = this.passWord
 7       let params = {
 8         username: userName,
 9         password: passWord
10       }
11       if (!userName || !passWord) {
12         this.loginLoading = false
13         this.$toast.error('账号或密码不能为空')
14       } else {
15         if ((userName.length < 51) && (passWord.length < 51)) {
16           let res = await userLogin(params)
17           this.loginBack(res)
18         } else {
19           this.loginLoading = false
20           this.$toast.error('账号或密码输入字符不能超过50位')
21         }
22       }
23     },
24     loginBack (res) {
25       let resBack = res.Back
26       let resData = res.Data
27       if (resBack === '1') {
28         ......
29       } else {
30         ......
31       }
32     }
33   }

  使用这种方式,需要注意的是方法内的函数需要时用: async await格式

  当然也可以不将接口统一管理而只用axios封装在组件内写函数:

 1 import axiosService from '../../../../axios/axios-request' /* 这里直接引入axios封装 */
 2 
 3 methods: {
 4     submitInfo () {
 5       let userName = localStorage.getItem('xyz')
 6       let dkId = this.nowLand.id
 7       let water = this.nowLand.water
 8       let status = this.nowLand.status
 9       let params = {
10         usename: userName,
11         dkid: dkId,
12         appwater: water
13       }
14       this.$confirm('是否提交申请?', '提示', {
15         type: 'warning'
16       }).then(({ result }) => {
17         if (result) {
18           if (status === 0) {
19            ......
20           } else {
21             axiosService({
22               url: '/HPGQ/waterrecord/addWaterRecord.action',
23               method: 'post',
24               params
25             }).then(this.applyBack)
26           }
27         } else {
28          ......
29         }
30       })
31     },
32     applyBack (res) {
33       ......
34     }
35   }

  以上是个人所用的封装方式,如有错误之处欢迎留言指正~~

posted @ 2019-03-26 14:49  建平正在学前端  阅读(1644)  评论(0编辑  收藏  举报