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,
}
相关推荐
陌小呆^O^12 分钟前
Cmakelist.txt之win-c-udp-client
c语言·开发语言·udp
I_Am_Me_27 分钟前
【JavaEE进阶】 JavaScript
开发语言·javascript·ecmascript
重生之我是数学王子37 分钟前
QT基础 编码问题 定时器 事件 绘图事件 keyPressEvent QT5.12.3环境 C++实现
开发语言·c++·qt
℘团子এ38 分钟前
vue3中如何上传文件到腾讯云的桶(cosbrowser)
前端·javascript·腾讯云
Ai 编码助手39 分钟前
使用php和Xunsearch提升音乐网站的歌曲搜索效果
开发语言·php
学习前端的小z43 分钟前
【前端】深入理解 JavaScript 逻辑运算符的优先级与短路求值机制
开发语言·前端·javascript
神仙别闹1 小时前
基于C#和Sql Server 2008实现的(WinForm)订单生成系统
开发语言·c#
XINGTECODE1 小时前
海盗王集成网关和商城服务端功能golang版
开发语言·后端·golang
前端百草阁1 小时前
【TS简单上手,快速入门教程】————适合零基础
javascript·typescript
彭世瑜1 小时前
ts: TypeScript跳过检查/忽略类型检查
前端·javascript·typescript