- 全局loading
- 单页面loading
- 局部loading
首先,在Store中定义 loading.ts
。
import { ElLoading } from 'element-plus'
import * as _ from 'lodash-es'
import { defineStore } from 'pinia'
import { ref } from 'vue'
export const useLoading = defineStore('loading', () => {
const loading = ref<boolean>(false)
const loadingCount = ref<number>(0)
const fullscreenLoading = ref()
async function showLoading({ fullscreen = false, text = '' } = {}) {
if (fullscreen) {
if (fullscreenLoading.value) {
fullscreenLoading.value.close()
}
fullscreenLoading.value = ElLoading.service({
lock: true,
text,
})
} else {
loadingCount.value++
if (loading.value) return
loading.value = true
}
}
const tryHideLoading = _.debounce(() => {
if (loadingCount.value > 0) return
loading.value = false
}, 300)
function hideLoading({ fullscreen = false } = {}) {
if (fullscreen) {
fullscreenLoading.value?.close()
} else {
loadingCount.value--
tryHideLoading()
}
}
return { loading, showLoading, hideLoading }
})
然后,再在 api.ts
的拦截器中使用。
import pinia from '@/stores'
import { useLoading } from '@/stores/loading'
import type {
AxiosInstance,
AxiosRequestConfig,
AxiosResponse,
InternalAxiosRequestConfig,
} from 'axios'
import axios from 'axios'
const { showLoading, hideLoading } = useLoading(pinia)
//...
class Api {
// request 拦截器
static setRequestInterceptor(instance: AxiosInstance) {
instance.interceptors.request.use(
(config: InternalAxiosRequestConfig) => {
showLoading(config.loading)
return config
},
(error: AxiosError) => {
hideLoading(error.config?.loading)
return Promise.reject(error) // 在调用的那边可以拿到(catch)你想返回的错误信息
},
)
}
// response 拦截器
static setResponseInterceptor(instance: AxiosInstance) {
instance.interceptors.response.use((response: AxiosResponse) => {
hideLoading(response.config.loading)
//...
})
}
//...
}
export default Api
最后,在需要的地方添加全局 loading。
局部loading:
<div class="form" v-loading="props.attributes?.showLoading && loading"><div>
import { storeToRefs } from 'pinia'
const { loading } = storeToRefs(useLoading())
全屏loading:
const {
data: { aside, collect, group },
} = await Api.get('/release/index', {
loading: {
text: '配置文件加载中...',
fullscreen: true,
},
})