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
/**
 * 该插件中包含了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项

    modules: [
        // https://go.nuxtjs.dev/axios
        '@nuxtjs/axios',
        
      ],

    axios: {
        proxy: true,
        prefix: '/api/',
        retry: { retries: 3 },
        common: {
          contentType: 'application/json',
        },
      },
    2.4:  store 中使用

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,
}

你可能感兴趣的:(javascript,开发语言,ecmascript)