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> </head>
<body> <body>
<div id="appLoading"></div>
<div id="app"></div> <div id="app"></div>
<script type="module" src="/src/main.ts"></script> <script type="module" src="/src/main.ts"></script>
</body> </body>

View File

@ -1,24 +1,18 @@
<script setup lang="ts"> <script setup lang="ts">
import { naiveI18nOptions } from '@/utils' import AppMain from './AppMain.vue'
import { darkTheme } from 'naive-ui' import AppLoading from './components/common/AppLoading.vue'
import { useAppStore } from './store'
const appStore = useAppStore() // 使 Suspense
const naiveLocale = computed(() => {
return naiveI18nOptions[appStore.lang] ? naiveI18nOptions[appStore.lang] : naiveI18nOptions.enUS
},
)
</script> </script>
<template> <template>
<n-config-provider <Suspense>
class="wh-full" inline-theme-disabled :theme="appStore.colorMode === 'dark' ? darkTheme : null" <!-- 异步组件 -->
:locale="naiveLocale.locale" :date-locale="naiveLocale.dateLocale" :theme-overrides="appStore.theme" <AppMain />
>
<naive-provider> <!-- 加载状态 -->
<router-view /> <template #fallback>
<Watermark :show-watermark="appStore.showWatermark" /> <AppLoading />
</naive-provider> </template>
</n-config-provider> </Suspense>
</template> </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 App from './App.vue'
import { installRouter } from '@/router'
import { installPinia } from '@/store'
import AppVue from './App.vue'
import AppLoading from './components/common/AppLoading.vue'
async function setupApp() { // 创建应用实例并挂载
// 载入全局loading加载状态 const app = createApp(App)
const appLoading = createApp(AppLoading) app.mount('#app')
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()