2.0.8 • Published 2 months ago

vue-axios-optimize v2.0.8

Weekly downloads
-
License
ISC
Repository
-
Last release
2 months ago

vue-axios-optimize使用说明

vue-axios-optimize是一个对axios请求优化的vue插件包,引入此包之后,并进行相关配置,即可轻松实现全局请求加载动画,重复请求时取消前面的请求或者阻止后面的请求,并且可实现请求并发数量控制以及接口缓存。 可阅读此文章 了解

安装

npm install vue-axios-optimize -S

axios版本

axios版本建议大于0.27.2 , 作者测试版本为 "^0.27.2"、"^1.3.4"

引入

在src/api目录下新建axios-optimize.js文件

api目录大致如下

src

api

modules

common-api.js

index.js

axios.js

axios-optimize.js

axios-optimize.js文件内容大致如下

import axios from "axios"
import instance from "@/api/axios"
import axiosOptimize from "vue-axios-optimize"
import store from "@/store"
import {MessageBox} from "element-ui"

const AxiosOptimize = new axiosOptimize(axios, instance, {
  maxReqNum: 2, // 同时最多请求数量 选配  默认 4 
  cacheNum: 2, // 缓存数量 选配  默认10
  responseTypesStr: "arraybuffer,blob", // 当axios请求设置 responseType为arraybuffer或blob时,直接返回原始数据 选配 
  showLoadingFun: (config, requestingNum) => { // 当需要加载动画的请求数量不为0时的回调函数
    store.commit("app/SET_LOADING_STATUS", true)
  },
  hideLoadingFun: (config, requestingNum) => { // 当需要加载动画的请求数量为0时的回调函数
    store.commit("app/SET_LOADING_STATUS", false)
  },
  responseResultFun: (res) => { // 响应数据格式化
    return res.data
  },
  openRefresh: true, // 是否开启无感知刷新token 以下配置均与无感知刷新token有关 如无需配置无感知刷新token 可忽略
  code: "code", // 判断响应码的字段标识  默认code
  accessToken: "accessToken", // headers存放accessToken的字段名 默认 accessToken 用于判断当前接口是否使用的最新的token
  accessTokenExpirationCode: 401, // accessToken过期时 接口响应状态码 默认 数字类型 401
  refreshTokenExpirationCode: 403, // 刷新token接口请求报错时的 响应状态码  默认 数字类型 403
  setAccessTokenFun: (config, accessToken) => { // 设置接口请求token的 并返回新的config 默认为 config.headers.Authorization = "Bearer " + accessToken
    config.headers.Authorization = "Bearer " + accessToken
    return config
  },
  getRefreshTokenFun: () => { // 获取refreshToken的方法
    return store.getters.refreshToken
  },
  getAccessTokenFun: () => { // 获取accessToken的方法
    return store.getters.accessToken
  },
  refreshTokenStore: (refreshToken) => { // 调用刷新token的方法 并将获取到的数据存储到cookie 且需要将接口返回的数据  resolve(data)
    return store.dispatch("user/refreshToken", refreshToken)
  },
  reloginFun: async(response) => { // 刷新token接口也报错后的处理逻辑 建议进行类似如下方法处理
    // 重新登录方法   弹框提示 点击确认后 建议清除 缓存中token等信息后 刷新页面
    MessageBox.alert(`${response.message}`, "提示", {
      confirmButtonText: "OK",
      showClose: false,
      callback: async(action) => {
        if (action === "confirm") {
          // 清除缓存中的token等信息
          store.commit("user/CLEAR_AUTH")
          // 刷新浏览器是为了 跳转登录页时query的redirect 会带上 当前页面地址(路由拦截处的逻辑)
          window.location.reload()
        }
      }
    })
  }
})

export default AxiosOptimize

axios.js的内容需要做些细微的更改 大致内容如下

import axios from "axios"
import Message from "@/plugins/reset-message.js"
import store from "@/store"

// 创建axios实例
const service = axios.create({
  baseURL: XXX,
  timeout: XXX // 请求超时时间
})

// request拦截器
service.interceptors.request.use(
  config => {
    const accessToken = store.getters.accessToken
    if (accessToken) {
      // 配置无感知刷新token时 建议请求头多加个 accessToken, 如为其他字段可 配置 为其他字段 用于判断当前接口携带的accessToken
      config.headers.accessToken = accessToken
      // 用于做接口权限标识
      config.headers.Authorization = "Bearer " + accessToken
    }

    return config
  },
  error => {
    // 需要return
    return Promise.reject(error)
  }
)

// respone拦截器
service.interceptors.response.use(
  async response => {

    const {data, config, status, request} = response
    // 如果自定义代码不是200,则判断为错误。
    if (status !== 200) {
      Message({
        message: data.message || "Error",
        type: "error",
        duration: 5 * 1000
      })
      // 错误响应时,多返回一个config 和 responseErr设置为true 让vue-axios-optimize 拿到config 以及知道 这是一个错误的响应数据
      return { ...data, config, responseErr: true}
    } else {
      // 二进制数据则直接返回
      if (request.responseType === "blob" || request.responseType === "arraybuffer"){
        // 直接返回数据
        return response
      }
      if (data.code === 200) {
        // 正常响应时,多返回一个config 让vue-axios-optimize 拿到config 
        return { ...data, config}
      }
      if (data.code === 401 || data.code === 403) {
        // 错误响应时,多返回一个config 和 responseErr设置为true 让vue-axios-optimize 拿到config 以及知道 这是一个错误的响应数据
        return { ...data, config, responseErr: true}
      }
      Message({
        message: data.message || "Error",
        type: "error",
        duration: 5 * 1000
      })
      // 错误响应时,多返回一个config 和 responseErr设置为true 让vue-axios-optimize 拿到config 以及知道 这是一个错误的响应数据
      return { ...data, config, responseErr: true}
    }
  },
  error => {
    // 取消请求时 不报错误信息
    if (error.name !== "CanceledError") {
      Message.error(error.message)
    }
    // 需要return
    return Promise.reject(error)
  }
)

export default service

接口处使用,如commo-api.js 大致如下

import axiosRequest from "@/api/axios-optimize"
// 需要配置 请求接口时 不加载全局动画 则 配置  noShowLoading: true
// 需要配置 缓存的接口 则 配置  cache: true 否则 配置为 false 或 不配置
// 需要配置 重复请求时 取消前面的请求 则 配置  preventDuplicateRequestsType: "cancel"
// 需要配置 重复请求时 禁用后面的请求 则 配置  preventDuplicateRequestsType: "prevent"
// 需要配置 返回数据是否添加 IS_COMPLETE 是否完成字段 则 配置  showIsComplete: true
// 需要配置 当同时请求很多接口,且还有很多接口在队列时,有接口报错,是否终止所有队列中的接口请求  removeRemainingTasksWhenError: true
// 需要配置 全路经(包括入参数据)为接口唯一标识的  则配置  fullPath: true 否则 配置为 false 或 不配置  否则仅仅以URL为唯一标识
// 当需要配置无感知刷新token时,对于刷新token接口需要配置 isRefreshToken 为true 否则配置为 false 或者不 配置

// get 请求demo
export function getDemo(
  data = {},
  config = {
    noShowLoading: true, // 配置不展示加载动画
    preventDuplicateRequestsType: "cancel" // 配置重复请求时 取消前面的请求
  }
) {
  return axiosRequest.get(`/xiaobu-admin/getDemo`, { params: data, ...config })
}

// post 请求demo
export function postDemo(data = {}, config = {}) {
  return axiosRequest.post(`/xiaobu-admin/postDemo`, data, config)
}

// delete 请求demo1 使用data作为参数 参数不展示在  请求路径上
export function deleteDemo1(data = {}, config = {}) {
  return axiosRequest.delete(`/xiaobu-admin/deleteDemo1`, { data, ...config })
}

// delete 请求demo2 使用params作为参数 参数展示在  请求路径上
export function deleteDemo2(data = {}, config = {}) {
  return axiosRequest.delete(`/xiaobu-admin/deleteDemo2`, {
    params: data,
    ...config
  })
}

// put 请求demo
export function putDemo(data = {}, config = {}) {
  return axiosRequest.put(`/xiaobu-admin/putDemo`, data, config)
}

// patch 请求demo
export function patchDemo(data = {}, config = {}) {
  return axiosRequest.patch(`/xiaobu-admin/patchDemo`, data, config)
}

new axiosOptimize(axios, instance, options)参数说明

参数说明来源
axios安装axios中的axiosimport axios from 'axios'
instance创建好的axios实例,已经配置好请求头等相关内容import instance from '@/api/axios.js'
options一些配置,详情继续阅读文档自定义配置

options配置

参数类型说明是否必传默认值
maxReqNumNumber同时最大可请求数量,高并发任务时,可同时进行的任务处理数量4
cacheNumNumber可缓存的键值对个数10
showLoadingFun(config, requestingNum)Function展示动画,config为该请求的config,requestingNum为目前正在请求几个接口,此处可执行一些展示全局动画的操作
hideLoadingFun(config, requestingNum)Function隐藏动画,config为该请求的config,requestingNum为目前正在请求几个接口,此时应该为0,此处可执行关闭全局动画的操作
openRefreshBoolean是否开启无感知刷新tokenfalse
refreshApiUrlString请求刷新token接口的api地址 如/xiaobu-admin/refresh-token当openRefresh为true时必传
getRefreshTokenFun()Function获取当前项目的 refreshToken方法, 记得 return 回去当openRefresh为true时必传
getAccessTokenFun()Function获取当前项目的 accessToken方法, 记得 return 回去当openRefresh为true时必传
reloginFun(response)Functionresponse 为axios实例中返回的数据,此处建议执行清除token相关缓存并弹框提示,点击确认进行刷新页面操作当openRefresh为true时必传
refreshTokenStore(refreshToken)FunctionrefreshToken为当前浏览器缓存的refreshToken,需要返回一个Promise,利用此refreshToken调用接口获取新的accessToken 并设置。v1.0.6及以上无需返回任何数据当openRefresh为true时必传
setAccessTokenFun(config, accessToken) (v1.0.8已废除, V2.0.2 弄回来 并添加默认值)Functionconfig为该请求的config,accessToken 为新获取的accessToken, 此处需要将accessToken设置到请求头中当openRefresh为true时必传setAccessTokenFun: (config, accessToken) => { // 设置接口请求token的 并返回新的config 默认为 config.headers.Authorization = "Bearer " + accessToken config.headers.Authorization = "Bearer " + accessToken return config },
responseResultFun(res)Functionres为axios实例返回的res,格式化接口请求成功后返回的数据非必传axios实例返回的res
formatAccessTokenFun(data) v1.0.6已废除Functiondata为responseResultFun报错时返回的res非必传axios实例返回的res.data.accessToken
accessTokenExpirationCodenumber配置accessToken过期返回的业务状态码非必传401
refreshTokenExpirationCodenumber配置refreshToken过期返回的业务状态码非必传403
responseTypesStr(v1.0.2)String配置数据返回类型,实现当此类型时返回原封不动的响应数据的data数据非必传

store/modules/user.js代码大致如下

import { setCookie, getCookie, removeCookie, accessTokenKey, refreshTokenKey } from "@/utils/cookie"
import { commonApi } from "@/api"

const getDefaultState = () => {
  return {
    accessToken: getCookie(accessTokenKey) || "", // 认证token
    refreshToken: getCookie(refreshTokenKey) || "", // 刷新token
  }
}
const state = getDefaultState()

const mutations = {
  // 重置初始化值
  RESET_STATE: (state) => {
    Object.assign(state, getDefaultState())
  },
  // 设置token
  SET_TOKEN: (state, data) => {
    const { accessToken, refreshToken, expiresIn} = data
    state.accessToken = accessToken
    setCookie(accessTokenKey, accessToken, expiresIn)
    state.refreshToken = refreshToken
    setCookie(refreshTokenKey, refreshToken, expiresIn)
  },

  // 清除token 及其他可能影响操作的缓存数据
  CLEAR_AUTH: (state) => {
    state.accessToken = ""
    removeCookie(accessTokenKey)
    state.refreshToken = ""
    removeCookie(refreshTokenKey)
    // ...
  }
}

const actions = {
  // 设置项目token
  setToken({commit}, data) {
    return new Promise((resolve, reject) => {
      commit("SET_TOKEN", data)
      resolve()
    })
  },
  // 刷新token
  refreshToken({commit}, refreshToken) {
    return new Promise((resolve, reject) => {
      commonApi.refreshToken({refreshToken}).then(data => {
        commit("SET_TOKEN", data)
        resolve()
      })
    })
  },
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

注意

如果要配置无感知刷新token时,对后端是有要求的,需要做到当accessToken过期refreshToken未过期时,请求接口的业务状态码 code为 配置的 accessTokenExpirationCode 的值, 默认401,当refreshToken过期或其他问题报错导致系统无法运行的错误时 业务状态码code 应为配置的 refreshTokenExpirationCode, 默认403

当部分页面接口请求在catch处有操作时 需添加语句, 参考如下示例

      this.loading = true
      testApi.getUserList(this.addDateRange(this.queryParams, this.dateRange)).then(res => {
        const response = res.data
        this.list = response.rows
        this.total = response.total
        this.loading = false
      }).catch(err => {
        // 此处需要添加 如果是取消请求 或者是 阻止请求时 不进行操作
        if (err.name === "CanceledError") {
          return
        }
        this.loading = false
      })

特别注意

vue2项目的vue.config.js 需要添加如下配置,对插件包进行编译。

module.exports = {
    ...
  transpileDependencies: [
    "vue-axios-optimize"
  ],
  	...
}

总结

如有疑问,可关注微信公众号【爆米花小布】进行咨询。

微信公众号

微信公众号【爆米花小布】,抖音号【爆米花小布】 更多好玩的插件

vue2-element-dict字典包插件

vue3-element-dict字典包插件

vue2-vant-dict移动端字典包插件

vue3-van3-dict移动端字典包插件

vue3-water-marker水印插件

vue2-water-marker水印插件

更新日志

2.0.8

  1. 【优化】新增showIsComplete参数,实现只有配置了才在请求返回数据中添加 IS_COMPLETE 是否请求完成字段。

2.0.6

  1. 【优化】新增removeRemainingTasksWhenError参数,实现当某个请求报错时,尽可能的阻止剩余未发起的请求。

2.0.5

  1. 【修复】接口报错时,原封不动reject返回原始数据

2.0.3

  1. 【修复】修复缓存接口时,取消重复请求,页面逻辑代码的catch不执行的问题

2.0.2

  1. 【功能】阻止重复请求的代码逻辑变更
  2. 【功能】无感知刷新token的代码逻辑变更
  3. 【修复】配置高并发请求数量后,取消请求存在取消不了的情况
  4. 【优化】配置接口缓存后,新增可删除接口缓存的功能
  5. 【注意】options配置变化,及接口捕获异常处的逻辑判断

2.0.1

  1. 【功能】实现接口缓存配置 options新增配置 cacheNum 配置最大缓存数量, 接口配置处可配置 cache: true。 注意:如下几种情况不建议配置缓存
    1. 表单提交的接口
    2. 数据频繁更新的接口
    3. 删除数据接口

2.0.0

  1. 【功能】实现并发请求数量控制,options新增maxReqNum参数配置 默认值为 4 ,表示同时可请求4个接口,剩余的接口陆续排队
  2. 【优化】当接口返回数据格式为对象格式时,会多添加一个 IS_COMPLETE 表示当前全部请求任务是否已完成
  3. 【调整】2.0.0版本 axios-optimize.js 文件不暴露 instance实例,且接口调用方法仅 支持 .get .post .delete .patch .put 形式调用, 具体查看文档示例

1.0.8

  1. 【优化】废除options的setAccessTokenFun配置项
  2. 【优化】将返回数据的config去除

1.0.6

  1. 【优化】废除options的formatAccessTokenFun配置项
  2. 【优化】refreshTokenStore由原来的resolve接口返回的数据,改为resolve(accessToken)

1.0.5

  1. 【优化】修复部分检查代码比较严格的时候 会报 responseType 未定义的错误的问题

1.0.3

  1. 【优化】修复部分检查代码比较严格的时候 会报 noShowLoading 未定义的错误的问题

1.0.2

  1. options新增responseTypesStr配置项,字符串类型,多个时使用英文逗号隔开,此返回类型的数据直接返回原有数据的data数据。在axios.js原封装函数中返回原始的响应返回数据。解决文件类型数据时不可用的问题

1.0.1

  1. 修复单词错误问题 isPervent 修改为 isPrevent

1.0.0

  1. 初始版本
2.0.8

2 months ago

2.0.6

2 months ago

2.0.5

3 months ago

2.0.3

5 months ago

2.0.2

5 months ago

2.0.1

5 months ago

2.0.0

5 months ago

1.0.8

8 months ago

1.0.6

8 months ago

1.0.5

8 months ago

1.0.3

8 months ago

1.0.2

8 months ago

1.0.1

9 months ago

1.0.0

9 months ago