feat: 全局 loading

This commit is contained in:
baiqi 2023-06-25 15:34:33 +08:00 committed by 刘瑞斌
parent 1fde986af6
commit e20e082658
7 changed files with 51 additions and 16 deletions

View File

@ -13,6 +13,7 @@
:collapsed="collapsed" :collapsed="collapsed"
:collapsible="true" :collapsible="true"
:width="menuWidth" :width="menuWidth"
:collapsed-width="collapsedWidth"
:style="{ paddingTop: navbar ? navbarHeight : '' }" :style="{ paddingTop: navbar ? navbarHeight : '' }"
:hide-trigger="true" :hide-trigger="true"
@collapse="setCollapsed" @collapse="setCollapsed"
@ -33,11 +34,13 @@
<Menu /> <Menu />
</a-drawer> </a-drawer>
<a-layout class="layout-content" :style="paddingStyle"> <a-layout class="layout-content" :style="paddingStyle">
<a-spin :loading="appStore.loading" :tip="appStore.loadingTip">
<TabBar v-if="appStore.tabBar" /> <TabBar v-if="appStore.tabBar" />
<a-layout-content> <a-layout-content>
<PageLayout /> <PageLayout />
</a-layout-content> </a-layout-content>
<Footer v-if="footer" /> <Footer v-if="footer" />
</a-spin>
</a-layout> </a-layout>
</a-layout> </a-layout>
</a-layout> </a-layout>
@ -68,8 +71,9 @@
const renderMenu = computed(() => appStore.menu && !appStore.topMenu); const renderMenu = computed(() => appStore.menu && !appStore.topMenu);
const hideMenu = computed(() => appStore.hideMenu); const hideMenu = computed(() => appStore.hideMenu);
const footer = computed(() => appStore.footer); const footer = computed(() => appStore.footer);
const collapsedWidth = 86;
const menuWidth = computed(() => { const menuWidth = computed(() => {
return appStore.menuCollapse ? 48 : appStore.menuWidth; return appStore.menuCollapse ? collapsedWidth : appStore.menuWidth;
}); });
const collapsed = computed(() => { const collapsed = computed(() => {
return appStore.menuCollapse; return appStore.menuCollapse;
@ -159,7 +163,7 @@
background-color: var(--color-bg-3); background-color: var(--color-bg-3);
transition: padding 0.2s cubic-bezier(0.34, 0.69, 0.1, 1); transition: padding 0.2s cubic-bezier(0.34, 0.69, 0.1, 1);
.arco-layout-content { .arco-layout-content {
padding: 16px 16px 0; padding: 16px 16px 16px 0;
} }
} }
</style> </style>

View File

@ -2,6 +2,9 @@ export default {
// 消息提醒相关 // 消息提醒相关
'message.errorTip': 'Error Tip', 'message.errorTip': 'Error Tip',
'message.logoutSuccess': 'Logout success', 'message.logoutSuccess': 'Logout success',
'message.menuLoading': 'Loading the menu...',
'message.menuLoadSuccess': 'Menu loaded successfully',
'message.menuLoadError': 'Menu load failed',
// API相关 // API相关
'api.apiTimeoutMessage': 'The interface request timed out, please refresh the page and try again!', 'api.apiTimeoutMessage': 'The interface request timed out, please refresh the page and try again!',
'api.apiRequestFailed': 'The interface request failed, please try again later!', 'api.apiRequestFailed': 'The interface request failed, please try again later!',

View File

@ -2,6 +2,9 @@ export default {
// 消息提醒相关 // 消息提醒相关
'message.errorTip': '错误提示', 'message.errorTip': '错误提示',
'message.logoutSuccess': '登出成功', 'message.logoutSuccess': '登出成功',
'message.menuLoading': '菜单加载中...',
'message.menuLoadSuccess': '菜单加载成功',
'message.menuLoadError': '菜单加载失败',
// API相关 // API相关
'api.apiTimeoutMessage': '接口请求超时,请刷新页面重试!', 'api.apiTimeoutMessage': '接口请求超时,请刷新页面重试!',
'api.apiRequestFailed': '请求出错,请稍候重试', 'api.apiRequestFailed': '请求出错,请稍候重试',

View File

@ -1,13 +1,15 @@
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
import { Notification } from '@arco-design/web-vue'; import { Notification } from '@arco-design/web-vue';
import type { NotificationReturn } from '@arco-design/web-vue/es/notification/interface';
import type { RouteRecordNormalized } from 'vue-router';
import defaultSettings from '@/config/settings.json'; import defaultSettings from '@/config/settings.json';
import { getMenuList } from '@/api/modules/user'; import { getMenuList } from '@/api/modules/user';
import { AppState } from './types'; import { useI18n } from '@/hooks/useI18n';
import type { AppState } from './types';
import type { NotificationReturn } from '@arco-design/web-vue/es/notification/interface';
import type { RouteRecordNormalized } from 'vue-router';
const useAppStore = defineStore('app', { const useAppStore = defineStore('app', {
state: (): AppState => ({ ...defaultSettings }), state: (): AppState => ({ ...defaultSettings, loading: false, loadingTip: '加载中...' }),
getters: { getters: {
appCurrentSetting(state: AppState): AppState { appCurrentSetting(state: AppState): AppState {
@ -22,6 +24,9 @@ const useAppStore = defineStore('app', {
getCustomTheme(state: AppState): string { getCustomTheme(state: AppState): string {
return state.customTheme as string; return state.customTheme as string;
}, },
getLoadingStatus(state: AppState): boolean {
return state.loading;
},
}, },
actions: { actions: {
@ -51,25 +56,26 @@ const useAppStore = defineStore('app', {
* *
*/ */
async fetchServerMenuConfig() { async fetchServerMenuConfig() {
const { t } = useI18n();
let notifyInstance: NotificationReturn | null = null; let notifyInstance: NotificationReturn | null = null;
try { try {
notifyInstance = Notification.info({ notifyInstance = Notification.info({
id: 'menuNotice', // Keep the instance id the same id: 'menuNotice', // Keep the instance id the same
content: 'loading', content: t('message.menuLoading'),
closable: true, closable: true,
}); });
const data = await getMenuList(); const data = await getMenuList();
this.serverMenu = data; this.serverMenu = data;
notifyInstance = Notification.success({ notifyInstance = Notification.success({
id: 'menuNotice', id: 'menuNotice',
content: 'success', content: t('message.menuLoadSuccess'),
closable: true, closable: true,
}); });
} catch (error) { } catch (error) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
notifyInstance = Notification.error({ notifyInstance = Notification.error({
id: 'menuNotice', id: 'menuNotice',
content: 'error', content: t('message.menuLoadError'),
closable: true, closable: true,
}); });
} }
@ -80,6 +86,20 @@ const useAppStore = defineStore('app', {
clearServerMenu() { clearServerMenu() {
this.serverMenu = []; this.serverMenu = [];
}, },
/**
* loading
*/
showLoading(tip = '加载中...') {
this.loading = true;
this.loadingTip = tip;
},
/**
* loading
*/
hideLoading() {
this.loading = false;
this.loadingTip = '加载中...';
},
}, },
}); });

View File

@ -15,6 +15,8 @@ export interface AppState {
device: string; device: string;
tabBar: boolean; tabBar: boolean;
serverMenu: RouteRecordNormalized[]; serverMenu: RouteRecordNormalized[];
loading: boolean;
loadingTip: string;
[key: string]: unknown; [key: string]: unknown;
} }

View File

@ -17,7 +17,7 @@ const formatTag = (route: RouteLocationNormalized): TabProps => {
const BAN_LIST = [REDIRECT_ROUTE_NAME]; const BAN_LIST = [REDIRECT_ROUTE_NAME];
const useAppStore = defineStore('tabBar', { const useTabBarStore = defineStore('tabBar', {
state: (): TabBarState => ({ state: (): TabBarState => ({
cacheTabList: new Set([DEFAULT_ROUTE_NAME]), cacheTabList: new Set([DEFAULT_ROUTE_NAME]),
tabList: [DEFAULT_ROUTE], tabList: [DEFAULT_ROUTE],
@ -92,4 +92,4 @@ const useAppStore = defineStore('tabBar', {
}, },
}); });
export default useAppStore; export default useTabBarStore;

View File

@ -74,10 +74,13 @@ const useUserStore = defineStore('user', {
clearToken(); clearToken();
removeRouteListener(); removeRouteListener();
appStore.clearServerMenu(); appStore.clearServerMenu();
appStore.hideLoading();
}, },
// 登出 // 登出
async logout() { async logout() {
try { try {
const appStore = useAppStore();
appStore.showLoading('正在退出登录...');
await userLogout(); await userLogout();
} finally { } finally {
this.logoutCallBack(); this.logoutCallBack();