nuxtjs中使用axios 有两种方法:
npm install axios -S
普通使用方式网上查询,这里不再过多叙述。
npm install @nuxtjs/axios --save
备注: 当使用脚手架create nuxt-app创建项目时,会提示是否集成axios。
/**
* 该插件中包含了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',
},
},
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,
}