nuxt.js中使用axios以及二次封装

nuxtjs中使用axios 有两种方法:

1. 普通的方式:

1.1: npm或者yarn安装依赖包

npm install axios -S

普通使用方式网上查询,这里不再过多叙述。

2. 集成的方式:

2.1:首先安装 @nuxtjs/axios

npm install @nuxtjs/axios --save

备注: 当使用脚手架create nuxt-app创建项目时,会提示是否集成axios。

2.2:在项目根目录新建plugins/axios.js
javascript 复制代码
/**
 * 该插件中包含了axios的各种配置,以及axios二次封装
 * 注释掉了全局引入loading的方法,页面采用局部loading,若有需求可以放开。
 * 1.token管理
 * 2.响应和请求的错误处理
 * 3.请求的loding控制
 *
 * 使用时:$axios为nuxtjs集成的axios;$axios为"@nuxtjs/axios": "^5.13.6",
 * 作者:
 */

import _ from 'lodash'
import Vue from 'vue'
import { Loading, Message } from 'element-ui'
import { uuid } from '~/plugins/utils/uuid'

let loadingInstance = null

let needLoadingRequestCount = 0

let securityCheckLock = false

// 显示loading
function showLoading(target) {
  // 后面这个判断很重要,因为关闭时加了抖动,此时loading对象可能还存在,
  // 但needLoadingRequestCount已经变成0.避免这种情况下会重新创建个loading
  if (needLoadingRequestCount === 0 && !loadingInstance) {
    loadingInstance = Loading.service({
      lock: true,
      text: 'Loading',
      spinner: 'el-icon-loading',
      background: 'rgba(0, 0, 0, 0.7)',
    })
  }
  needLoadingRequestCount++
}

// 隐藏loading
function hideLoading() {
  needLoadingRequestCount--
  needLoadingRequestCount = Math.max(needLoadingRequestCount, 0) // 做个保护
  if (needLoadingRequestCount === 0) {
    // 关闭loading
    toHideLoading()
  }
}

// 防抖:将 300ms 间隔内的关闭 loading 便合并为一次。防止连续请求时, loading闪烁的问题。
const toHideLoading = _.debounce(() => {
  if (loadingInstance) {
    loadingInstance.close()
    loadingInstance = null
  }
}, 300)

// 如果想用redirect或者操作vuex的话需要对外暴露store和redirect
export default ({
  store,
  redirect,
  req,
  $axios,
  app,
  ...args
}) => {
  // 请求拦截器,后续的token管理配置在这里
  $axios.onRequest(
    (config) => {
      if (process.client) {
        // 浏览器执行的客户端代码
        if (config.headers.showLoading !== false) {
          // showLoading(config.headers.loadingTarget)
        }
      }
      if (process.server) {
        // node执行的服务端代码
        // node服务端做host穿透-重点在这里哟
        // config.headers.host = req.headers.host
        if (!config.url.includes(process.env.baseUrl)) {
          config.url = process.env.baseUrl + config.url
        }
      }

      const token = Vue.prototype.$sdk.getUser().authUser 
      if (token) {
        config.headers.authorization = 'Bearer ' + token
      }

      config.headers.traceId = uuid(32) // traceId,用于后端追踪日志

      return config
    },
    // 请求错误处理,暂时所有都提示
    (err) => {
      // 判断当前请求是否设置了不显示Loading(不显示自然无需隐藏)
      if (err.config.headers.showLoading !== false) {
        hideLoading()
      }

      if (process.client) {
        Message.closeAll()
        Message.error({
          showClose: true,
          message: err,
        })
      }

      return Promise.reject(err)
    }
  )
  // 响应拦截器,处理header、config等数据,给应用层返回最简洁的数据data
  $axios.onResponse((res) => {
    const { data, headers } = res
    // 判断当前请求是否设置了不显示Loading
    if (headers?.showLoading !== false) {
      hideLoading()
    }
    if (data?.code === -1) {
      // 常规错误处理
      if (process.client) {
        Message.closeAll()
        Message.error({
          showClose: true,
          message: data.message,
        })
      }
    } else if (data?.type === 'application/json') {
      // 常规错误处理
      if (process.client) {
        Message.closeAll()
        Message.error({
          showClose: true,
          message: '文件不存在',
        })
      }
    } else if (data?.code === -555) {
      // token过期处理
      if (process.client) {
        Message.closeAll()
        Message.error({
          showClose: true,
          message: '登录过期,请重新登录!',
        })
        sessionStorage.clear()
      }
      redirect({
        path: '/login',
      }) //  跳转到登录页,或使用vuex提交数据
    } 

    if (data?.type === 'application/octet-stream') {
      return { data, headers }
    } else {
      return headers === undefined ? res : data
    }
  })
  // Error拦截器,出现错误的时候被调用
  $axios.onError((error) => {
    switch (error.response.status) {
      case 400:
        error.message = '请求错误'
        break

      case 401:
        error.message = '未授权,请登录'
        break

      case 403:
        error.message = '拒绝访问'
        break

      case 404:
        error.message = `请求地址出错: ${error.response.config.url}`
        break

      case 408:
        error.message = '请求超时'
        break

      case 500:
        error.message = '服务器内部错误'
        break

      case 501:
        error.message = '服务未实现'
        break

      case 502:
        error.message = '网关错误'
        break

      case 503:
        error.message = '服务不可用'
        break

      case 504:
        error.message = '网关超时'
        break

      case 505:
        error.message = 'HTTP版本不受支持'
        break
    }

    Message.error({
      showClose: true,
      message: error.message,
    })

    return Promise.resolve(false)
  })
}

2.3: nuxt.config.js中配置axios项

javascript 复制代码
    modules: [
        // https://go.nuxtjs.dev/axios
        '@nuxtjs/axios',
        
      ],

    axios: {
        proxy: true,
        prefix: '/api/',
        retry: { retries: 3 },
        common: {
          contentType: 'application/json',
        },
      },
2.4: store 中使用
javascript 复制代码
const baseUrl = '/base-service'

const state = () => ({

})

const mutations = {

}

const actions = {
  // 获取引擎列表
  async getList({ commit }, data) {
    return await this.$axios.post(
      `${baseUrl}/enginess/pageEnginesss`,
      data
    )
  },
  
}

export default {
  namespaced: true,
  state,
  mutations,
  actions,
}
相关推荐
binishuaio6 分钟前
Java 第11天 (git版本控制器基础用法)
java·开发语言·git
zz.YE7 分钟前
【Java SE】StringBuffer
java·开发语言
就是有点傻12 分钟前
WPF中的依赖属性
开发语言·wpf
洋24020 分钟前
C语言常用标准库函数
c语言·开发语言
进击的六角龙22 分钟前
Python中处理Excel的基本概念(如工作簿、工作表等)
开发语言·python·excel
wrx繁星点点23 分钟前
状态模式(State Pattern)详解
java·开发语言·ui·设计模式·状态模式
熊的猫31 分钟前
JS 中的类型 & 类型判断 & 类型转换
前端·javascript·vue.js·chrome·react.js·前端框架·node.js
NoneCoder40 分钟前
Java企业级开发系列(1)
java·开发语言·spring·团队开发·开发
苏三有春40 分钟前
PyQt5实战——UTF-8编码器功能的实现(六)
开发语言·qt
Aniay_ivy1 小时前
深入探索 Java 8 Stream 流:高效操作与应用场景
java·开发语言·python