fix: use suspense for apploading

This commit is contained in:
chansee97 2025-08-05 22:24:14 +08:00
parent a1085e1922
commit ade869ea30
4 changed files with 73 additions and 53 deletions

View File

@ -9,7 +9,6 @@
</head>
<body>
<div id="appLoading"></div>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>

View File

@ -1,24 +1,18 @@
<script setup lang="ts">
import { naiveI18nOptions } from '@/utils'
import { darkTheme } from 'naive-ui'
import { useAppStore } from './store'
import AppMain from './AppMain.vue'
import AppLoading from './components/common/AppLoading.vue'
const appStore = useAppStore()
const naiveLocale = computed(() => {
return naiveI18nOptions[appStore.lang] ? naiveI18nOptions[appStore.lang] : naiveI18nOptions.enUS
},
)
// 使 Suspense
</script>
<template>
<n-config-provider
class="wh-full" inline-theme-disabled :theme="appStore.colorMode === 'dark' ? darkTheme : null"
:locale="naiveLocale.locale" :date-locale="naiveLocale.dateLocale" :theme-overrides="appStore.theme"
>
<naive-provider>
<router-view />
<Watermark :show-watermark="appStore.showWatermark" />
</naive-provider>
</n-config-provider>
<Suspense>
<!-- 异步组件 -->
<AppMain />
<!-- 加载状态 -->
<template #fallback>
<AppLoading />
</template>
</Suspense>
</template>

57
src/AppMain.vue Normal file
View File

@ -0,0 +1,57 @@
<script setup lang="ts">
import type { App } from 'vue'
import { installRouter } from '@/router'
import { installPinia } from '@/store'
import { naiveI18nOptions } from '@/utils'
import { darkTheme } from 'naive-ui'
import { useAppStore } from './store'
// Promise -
const initializationPromise = (async () => {
//
const app = getCurrentInstance()?.appContext.app
if (!app) {
throw new Error('Failed to get app instance')
}
// Pinia
await installPinia(app)
// Vue-router
await installRouter(app)
// /
const modules = import.meta.glob<{ install: (app: App) => void }>('./modules/*.ts', {
eager: true,
})
Object.values(modules).forEach(module => app.use(module))
return true
})()
// - 使 setup
await initializationPromise
const appStore = useAppStore()
const naiveLocale = computed(() => {
return naiveI18nOptions[appStore.lang] ? naiveI18nOptions[appStore.lang] : naiveI18nOptions.enUS
})
</script>
<template>
<n-config-provider
class="wh-full"
inline-theme-disabled
:theme="appStore.colorMode === 'dark' ? darkTheme : null"
:locale="naiveLocale.locale"
:date-locale="naiveLocale.dateLocale"
:theme-overrides="appStore.theme"
>
<naive-provider>
<router-view />
<Watermark :show-watermark="appStore.showWatermark" />
</naive-provider>
</n-config-provider>
</template>

View File

@ -1,35 +1,5 @@
import type { App } from 'vue'
import { installRouter } from '@/router'
import { installPinia } from '@/store'
import AppVue from './App.vue'
import AppLoading from './components/common/AppLoading.vue'
import App from './App.vue'
async function setupApp() {
// 载入全局loading加载状态
const appLoading = createApp(AppLoading)
appLoading.mount('#appLoading')
// 创建vue实例
const app = createApp(AppVue)
// 注册模块Pinia
await installPinia(app)
// 注册模块 Vue-router
await installRouter(app)
/* 注册模块 指令/静态资源 */
Object.values(
import.meta.glob<{ install: (app: App) => void }>('./modules/*.ts', {
eager: true,
}),
).map(i => app.use(i))
// 卸载载入动画
appLoading.unmount()
// 挂载
app.mount('#app')
}
setupApp()
// 创建应用实例并挂载
const app = createApp(App)
app.mount('#app')