沃梦达 / IT编程 / 移动开发 / 正文

vue的axios配置与api封装

话不多少,上代码(fetch文件):import Vue from vueimport axios from axiosimport Store from ../vuex/store.js //运用到Vuex可使用const QS = require(qs)/*** 开发配置baseUrl*/// const PRIVARY_UR...

话不多少,上代码(fetch文件):

import Vue from 'vue'
import axios from 'axios'
import Store from '../vuex/store.js' //运用到Vuex可使用
const QS = require('qs')

/**
 * 开发配置baseUrl
 */
// const PRIVARY_URL = '/quality' // 生产
const PRIVARY_URL = '/dev' // 开发

/**
 *
 * 生产配置baseUrl
 */
const PROXY_URL = '/qualitydev'
axios.defaults.baseURL = process.env.NODE_ENV === 'production' ? PROXY_URL : PRIVARY_URL

axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'
Vue.prototype.$baseUrls = axios.defaults.baseURL
axios.defaults.timeout = 30000

// 重新请求
axios.defaults.retry = 360
axios.defaults.retryDelay = 10000

let pending = [] // 声明一个数组用于存储每个 ajax 请求的取消函数和ajax标识
let CancelToken = axios.CancelToken
let removePending = (ever) => {
  /**
   * TODO: 对极短时间内相同的重复请求拦截,阻止请求(防止按钮重复点击,发出多次相同请求)
   */
  for (let p in pending) {
    if (pending[p].u === ever.url + '&' + ever.method + '&' + JSON.stringify(ever.params)) { // 当当前请求在数组中存在时执行函数体
      // pending[p].cancle('重复操作') // 执行取消操作
      pending.splice(p, 1) // 把这条记录从数组中移除
    }
  }
}
var vue = new Vue()
// Add a request interceptor

//请求拦截器
axios.interceptors.request.use(
  config => {
   //每个请求都有的默认的参数,可以是登陆之后的用户信息
    const appId = 'QUALITY_WEB'
    let user = (new Vue())._util.getUser()
    if (user) {
      const userKey = user.userKey
      config.params = {
        userKey,
        appId,
        ...config.params
      }
      //请求头封装参数
      config.headers.userId = user.id
      config.headers.token = user.userKey
    } else {
      config.params = {
        appId,
        ...config.params
      }
    }
    removePending(config) // 在一个ajax发送前执行一下取消操作
    config.cancelToken = new CancelToken((c) => {
      // 这里的ajax标识是用请求地址&请求方式&请求参数拼接的字符串,也可以选择其他的一些方式
      pending.push({ u: config.url + '&' + config.method + '&' + JSON.stringify(config.params), cancle: c })
    })
    return config
  },
  error => {
    return Promise.reject(error)
  }
)

// Add a response interceptor
//响应拦截
axios.interceptors.response.use(
  response => { // 如果返回的数据中status不为1,则全局警告
    // ------------------------------------------------------------------------------------------
    removePending(response.config) // 在一个ajax响应后再执行一下取消操作,把已经完成的请求从pending中移除
    // ------------------------------------------------------------------------------------------
    if (response.data && response.data.status !== 1) {
      if (response.data.message) {
        myMessage.warning(response.data.message)
      }
      // 登录失效
      if (response.data.status === 0) {
        Store.commit('SET_USER', null)
        Store.commit('screen_boo', false)
      }
    }
    vue.$loading.hide()
    return response
  },
  error => { // 返回状态码不为200时候的错误处理
    // var RetryNetwork = function () {
    //   let config = error.config
    //   // If config does not exist or the retry option is not set, reject
    //   if (!config || !config.retry) return Promise.reject(error)
    //   // Set the variable for keeping track of the retry count
    //   config.__retryCount = config.__retryCount || 0
    //   // Check if we've maxed out the total number of retries
    //   if (config.__retryCount >= config.retry) {
    //     // Reject with the error
    //     return Promise.reject(error)
    //   }
    //   // Increase the retry count
    //   config.__retryCount += 1
    //   // Create new promise to handle exponential backoff
    //   let backoff = new Promise(resolve => {
    //     setTimeout(() => {
    //       resolve()
    //     }, config.retryDelay || 3000)
    //   })
    //   return backoff.then(function () {
    //     // check config.url and then remove the baseUrl from cinfig.url
    //     let reg = new RegExp(config.baseURL)
    //     config.url = config.url.replace(reg, '')
    //
    //     return axios(config)
    //   })
    // }
    // vue.$loading.button()
    if (error.message === '重复操作') {
      // myMessage.error('请勿多次重复操作')
      setTimeout(() => {
        vue.$loading.hide()
      }, 1000)
    }
    // 有一种可能是断网了
    if (!error.response && error.message !== '重复操作') { // 超时
      myMessage.error('断网--请求超时, ::NET-DISCONNECT')
      // RetryNetwork()
      setTimeout(() => {
        vue.$loading.hide()
      }, 1000)
    }
    if (error && error.response && error.response.status) {
      switch (error.response.status) {
        case 400:
          myMessage.error('请求错误')
          break
        case 401:
          myMessage.error('未授权,请登录')
          break
        case 403:
          myMessage.error('拒绝访问')
          break
        case 404:
          myMessage.error('请求路径出错: 404 NOT FOUND')
          // RetryNetwork()
          break
        case 408:
          myMessage.error('请求超时, ::CODE 408')
          break
        case 500:
          myMessage.error('服务器内部错误')
          break
        case 501:
          myMessage.error('服务未实现')
          break
        case 502:
          myMessage.error('网关错误')
          break
        case 503:
          myMessage.error('服务不可用')
          break
        case 504:
          myMessage.error('网关超时, ::SERVER 504')
          // RetryNetwork()
          break
        default:
          myMessage.error('未知错误', error.response.status)
          break
      }
      setTimeout(() => {
        vue.$loading.hide()
      }, 1000)
    }
    return Promise.reject(error)
  }
)

function transformRequest (data, options) {
  let temp = data
  // 把一个参数对象格式化为一个字符串
  if (!options.isJson) {
    temp = QS.stringify(data)
  }
  // 上传用formData封装
  if (options.isUpload) {
    let formData = new FormData()
    for (let key in data) {
      formData.append(key, data[key])
    }
    temp = formData
  }
  return temp
}

export default axios(url = '', params = {}, method = 'get', options = { isUpload: false, isJson: false }) => {
  if (!params.hideLoading) {
    vue.$loading.show()
  }
  method = method.toLowerCase()
  if (method === 'get') {
    let paramArr = []
    for (let [key, value] of Object.entries(params)) {
      paramArr.push(key + '=' + value)
    }
    if (paramArr.length > 0) {
      url += '?' + paramArr.join('&').replace(/#/g, '%23')
    }
    return new Promise((resolve, reject) => {
      axios
        .get(url)
        .then(
          response => {
            resolve(response.data)
          },
          err => {
            reject(err)
          }
        )
        .catch(error => {
          reject(error)
        })
    })
  } else if (method === 'post') {
    let config = {}
    if (options.isUpload) {
      config = {
        headers: {
          'Content-Type': 'multipart/form-data'
        }
      }
    }
    // should we use type:'application/x-www-form-urlencoded' to send the data?
    params = transformRequest(params, options)
    return new Promise((resolve, reject) => {
      axios
        .post(url, params, config)
        .then(
          response => {
            resolve(response.data)
          },
          err => {
            reject(err)
          }
        )
        .catch(error => {
          reject(error)
        })
    })
  } else if (method === 'put') {
    return new Promise((resolve, reject) => {
      axios
        .put(url, params)
        .then(
          response => {
            resolve(response.data)
          },
          err => {
            reject(err)
          }
        )
        .catch(error => {
          reject(error)
        })
    })
  } else if (method === 'delete') {
    return new Promise((resolve, reject) => {
      axios
        .delete(url)
        .then(
          response => {
            resolve(response.data)
          },
          err => {
            reject(err)
          }
        )
        .catch(error => {
          reject(error)
        })
    })
  } else {
    let error = '传递的参数错误'
    return Promise.reject(error)
  }
}

api层级封装(index文件):

import fetch from './fetch'
// 教师端  首页
import teacherHome from './xxxx'
// 教师端  项目化学习方案定义
import teacherLearn from './xxxxx'
// 教师端  项目化学习课程实例
import teacherCourse from './xxxxx'
// 教师端  实践活动
import teacherPractica from './xxxxxx'
// 教师端  日常评价
import teacherEvaluation from './xxxxxxx'
// 教师端  学生个体评价
import teacherIndividual from './xxxxxx'
// 教师端  平台入口
import teacherPlatform from './xxxxxxxx'
// 教师端 权限管理
import teacherAuthority from './xxxxxxx'
// 导入数据
import guidedData from './xxxxxxxx'
// 学生端
import studentCourse from './xxxxxxx'
// 教师端综评管理
import teacherMament from './xxxxxx.js'
// 教师端学习任务
import teacherStudyTask from './xxxxxxxx.js'
// 教师端体质健康
import teacherHealth from './xxxxxxx.js'
import teacherCreateRecords from './xxxxxxxxxxx'

export default {
  login (deviceId, account, password) {
    return fetch(`/xxxxxx`, { deviceId, account, password }, 'get')
  },
  smsUpdatePhone (id, deviceId, phone, zone, verifyCode, system, appId) { // 绑定手机号
    return fetch('newUser/xxxxxxx', {id, deviceId, phone, zone, verifyCode, system, appId}, 'get')
  },
  sendMsg (phone, zone, system) { // 发送短信
    return fetch('user/xxxxx', {phone, zone, system}, 'get')
  },
  smsLogin (deviceId, phone, zone, verifyCode, system) { // 手机号登录
    return fetch('/newUser/xxxx', {deviceId, phone, zone, verifyCode, system}, 'get')
  },
  getToken (bucketType, fileType) {
    return fetch('file/xxxx', { bucketType, fileType }, 'post')
  },
  qnUpload (key, token, file) {
    return fetch('https://upload.qiniu.com', { key, token, file }, 'post', { isUpload: true })
  },
  findGradeSubjects () {
    return fetch('/school/check/xxxxxxx', {}, 'get')
  },
  findSchoolInfo () {
    return fetch('schoolInfo/check/xxxxxxxx', { }, 'get')
  },
  systemlogin (systemUserId) {
    return fetch('userSystemInfo/xxxxxxx', {systemUserId}, 'post', { isUpload: true })
  },
  ...teacherHome,
  ...teacherLearn,
  ...teacherCourse,
  ...teacherPractica,
  ...teacherEvaluation,
  ...teacherIndividual,
  ...teacherPlatform,
  ...teacherAuthority,
  ...guidedData,
  ...studentCourse,
  ...teacherMament,
  ...teacherStudyTask,
  ...teacherHealth,
  ...teacherCreateRecords
}

某一个页面接口文件:

import fetch from './fetch'

export default {
  // 任务实例
  getCourseTask (type, time) {
    return fetch('course/check/xxxxx', {type, time}, 'get')
  },
  // 开课获取课程列表的接口
  getCourseList (subject) {
    return fetch('course/check/xxxxx', {subject}, 'get')
  },
  // 根据年级学科,获取教师名单
  getGradeSubject (grade, subject, hideLoading = true) {
    return fetch('user/check/xxxxxxxx', {grade, subject, hideLoading}, 'get')
  },
  // 学生导入
  inputStudent (students, grades) {
    return fetch('course/check/xxxxxxxx', {students, grades}, 'post', {isUpload: true})
  },
  // 开课请求
  startCourse (courseId, ownerId, teacherIds, groupCount, studentIds, errorList) {
    return fetch('course/check/xxxxxxxx', {courseId, ownerId, teacherIds, groupCount, studentIds, errorList}, 'post', {isJson: true})
  }

在main.js中全局注册:

...
import axios from '@/http'
...
 Vue.prototype.$http = axios
...

本文标题为:vue的axios配置与api封装