1

成功者心中容得下世界,失败者眼里只有对方

vue开发中为了统一管理接口,我们需要对axios进行二次封装,配置一些东西

一、创建目录和文件

在src目录下面创建request目录,并创建api.js和http.js文件
image.png

二、配置http.js文件

// 引入axios
import axios from 'axios'
// 引入stroe
import store from '@/store/index'
// 引入router
import router from '@/router/index'
// elementUi消息提示组件。
import { Message } from 'element-ui'
// iviewUI框架的loadingbar组件,浏览器顶部加载动画
import {LoadingBar} from 'iview'
// 配置请求取消,在搜索等场景,输入比较快,接口调取频繁的情况
// 声明一个数组用于存储每个请求的取消函数和axios标识
let pending = []
const CancelToken = axios.CancelToken
let removePending = (config) => {
  for (let p in pending) {
    if (pending[p].u === config.url + JSON.stringify(config.data) + '&' + config.method) {
      pending[p].f()
      pending.splice(p, 1)
    }
  }
}
// 环境的参数
console.log(process.env.NODE_ENV, process.env.ENV_CONFIG, '环境参数')
// 根据不同环境配置不同的请求地址
if (process.env.NODE_ENV === 'development') {
  console.log(router, store, 'http.js中的路由器信息')
  axios.defaults.baseURL = 'https://api.bangzhu.tech/new_simulate'
} else if (process.env.NODE_ENV === 'testing') {
  axios.defaults.baseURL = 'https://api.bangzhu.tech/new_simulate'
} else if (process.env.NODE_ENV === 'production') {
  axios.defaults.baseURL = 'https://www.bangzhu.tech/api'
}
// 设置请求最大时长,超时请求接口失败。
axios.defaults.timeout = 50000
// 设置请求header参数
axios.defaults.headers.post['Content-Type'] = 'application/json; charset=UTF-8'
// 设置请求参数By-User-Info: 8(userid)
axios.defaults.headers.common['By-User-Info'] = localStorage.getItem('userInfo_admin') ? JSON.parse(localStorage.getItem('userInfo_admin')).user_id : ''
// 携带请求cookie
axios.defaults.withCredentials = true
// 请求拦截器
axios.interceptors.request.use(config => {
// 取消请求
  removePending(config)
  config.cancelToken = new CancelToken((c) => {
    // 这里的axios标识我是用请求地址&请求方式拼接的字符串,当然你可以选择其他的一些方式
    pending.push({ u: config.url + JSON.stringify(config.data) + '&' + config.method, f: c })
  })
  // 配置request请求头header中的Authorization,如果登陆了就有Authorization就设置一下
  if (store.state.userInfo && store.state.userInfo.Authorization) {
    const token = store.state.userInfo.Authorization
    token && (config.headers.Authorization = token)
  }
  return config
}, error => {
  Message.error({
    message: '请求接口出错',
    duration: 3000
  })
  return Promise.error(error)
})

// 响应拦截器
axios.interceptors.response.use(response => {
  // 如果返回的状态码为200,说明接口请求成功,可以正常拿到数据
  // 取消响应
  removePending(response.config)
  // 否则的话抛出错误
  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:
        Message.error({
          message: '无权限',
          duration: 1000
        })
        router.replace({name: 'login'})
        break
      // 403 token过期
      // 登录过期对用户进行提示
      // 清除本地token和清空vuex中token对象
      // 跳转登录页面
      case 403:
        Message.error({
          message: '登录过期,请重新登录',
          duration: 1000
        })
        // 清除token
        localStorage.removeItem('token')
        // 跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面
        localStorage.clear()
        store.dispatch('loginOut')
        break
        // 404请求不存在
      case 404:
        Message.error({
          message: '网络请求不存在',
          duration: 1500
        })
        break
      // 其他错误,直接抛出错误提示
      default: {
        Message.error({
          message: error.response.data.message,
          duration: 1500
        })
      }
    }
    return Promise.reject(error.response)
  }
})

export function get (url, params, config) {
  // 如果是form/data提交信息
  if (config) {
    axios.defaults.headers.post['Content-Type'] = 'multipart/form-data'
  }
  LoadingBar.start()
  return new Promise(async (resolve, reject) => {
    axios.get(url, {
      params: params
    }).then(res => {
      resolve(res.data)
      LoadingBar.finish()
    }).catch(err => {
      reject(err.data)
      LoadingBar.error()
    })
  })
}
export function post (url, params, config) {
  // 如果请求头需要特殊设置
  if (config) {
    axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
  }
  LoadingBar.start()
  return new Promise((resolve, reject) => {
    axios.post(
      url,
      params
    ).then(res => {
      resolve(res.data)
      LoadingBar.finish()
    }).catch(err => {
      reject(err.data)
      LoadingBar.error()
    })
  })
}

export function put (url, params) {
  LoadingBar.start()
  console.log(window.location.hash)
  return new Promise((resolve, reject) => {
    axios.put(
      url,
      params
    ).then(res => {
      resolve(res.data)
      LoadingBar.finish()
    }).catch(err => {
      reject(err.data)
      LoadingBar.error()
    })
  })
}

三、配置api.js文件

我将所有的接口都配置在,api.js文件中,修改接口名称等比较方便,容易定位。

// 1、引入http.js中导出的get/post/put方法
import {get, post, put} from './http'
// 2、定义接口,退出登录接口和参数
export const LOGIN_OUT = params => get('/auth/login_out', params)
// 微信登录接口
export const WECHAT_LOGIN = params => post('/index.php/login/wechat', params)

四、接口使用

// 引入需要使用的接口
import {LOGIN_OUT, WECHAT_LOGIN} from '@/request/api'
...
export default {
    ...
    methods: {
        gotoLogin () {
            let params = {
                username: '',
                password: ''
            }
            // 接口使用
            WECHAT_LOGIN(params).then(res => {
                console.log(res)
            }).catch(error => {
                console.log(error)
            })
        }
    }
}

张旭超
1.4k 声望222 粉丝

精通 html+div+css jquery, vue, angularjs, angular2, angular4, ionic, ionic2