fix: When refreshing the page, the topic is wrong

pull/48/MERGE
vben 2024-05-25 22:43:22 +08:00
parent 352119cc3a
commit f2644dbbc5
11 changed files with 38 additions and 24 deletions

View File

@ -1,2 +1,4 @@
# spa-title # spa-title
VITE_GLOB_APP_TITLE = Vben Admin Pro VITE_GLOB_APP_TITLE = Vben Admin Pro
VITE_APP_NAMESPACE = antd-view

View File

@ -8,14 +8,14 @@ import { createApp } from 'vue';
import App from './app.vue'; import App from './app.vue';
import { router } from './router'; import { router } from './router';
async function bootstrap(namespace: string, env: string) { async function bootstrap(namespace: string) {
const app = createApp(App); const app = createApp(App);
// 国际化 i18n 配置 // 国际化 i18n 配置
await setupI18n(app, { defaultLocale: preference.locale }); await setupI18n(app, { defaultLocale: preference.locale });
// 配置 pinia-store // 配置 pinia-store
await setupStore(app, { env, namespace }); await setupStore(app, { namespace });
// 配置路由及路由守卫 // 配置路由及路由守卫
app.use(router); app.use(router);

View File

@ -6,17 +6,16 @@ import { overridesPreference } from './preference';
* *
*/ */
async function initApplication() { async function initApplication() {
const namespace = 'antd-view';
const env = import.meta.env.PROD ? 'prod' : 'dev'; const env = import.meta.env.PROD ? 'prod' : 'dev';
const namespace = `${import.meta.env.VITE_APP_NAMESPACE}-${env}`;
// app偏好设置初始化 // app偏好设置初始化
await setupPreference({ await setupPreference({
env,
namespace, namespace,
overrides: overridesPreference, overrides: overridesPreference,
}); });
import('./bootstrap').then((m) => m.bootstrap(namespace, env)); import('./bootstrap').then((m) => m.bootstrap(namespace));
} }
initApplication(); initApplication();

View File

@ -2,7 +2,7 @@ import type { UserConfig } from 'vite';
import { resolve } from 'node:path'; import { resolve } from 'node:path';
import { defineConfig, mergeConfig } from 'vite'; import { defineConfig, loadEnv, mergeConfig } from 'vite';
import { getApplicationConditionPlugins } from '../plugins'; import { getApplicationConditionPlugins } from '../plugins';
import { getCommonConfig } from './common'; import { getCommonConfig } from './common';
@ -14,12 +14,13 @@ function defineApplicationConfig(options: DefineAppcationOptions = {}) {
const { appcation = {}, vite = {} } = options; const { appcation = {}, vite = {} } = options;
const root = process.cwd(); const root = process.cwd();
const isBuild = command === 'build'; const isBuild = command === 'build';
// const env = loadEnv(mode, root); const env = loadEnv(mode, root);
const plugins = await getApplicationConditionPlugins({ const plugins = await getApplicationConditionPlugins({
compress: false, compress: false,
compressTypes: ['brotli', 'gzip'], compressTypes: ['brotli', 'gzip'],
devtools: true, devtools: true,
env,
extraAppConfig: true, extraAppConfig: true,
html: true, html: true,
i18n: true, i18n: true,

View File

@ -86,6 +86,7 @@ async function getApplicationConditionPlugins(
): Promise<PluginOption[]> { ): Promise<PluginOption[]> {
// 单独取否则commonOptions拿不到 // 单独取否则commonOptions拿不到
const isBuild = options.isBuild; const isBuild = options.isBuild;
const env = options.env;
const { const {
compress, compress,
@ -123,7 +124,7 @@ async function getApplicationConditionPlugins(
}, },
{ {
condition: injectAppLoading, condition: injectAppLoading,
plugins: async () => [await viteInjectAppLoadingPlugin()], plugins: async () => [await viteInjectAppLoadingPlugin(isBuild, env)],
}, },
{ {
condition: isBuild && !!compress, condition: isBuild && !!compress,

View File

@ -8,8 +8,22 @@ import { type PluginOption } from 'vite';
* loading * loading
* apploading app -> index.html * apploading app -> index.html
*/ */
async function viteInjectAppLoadingPlugin(): Promise<PluginOption | undefined> { async function viteInjectAppLoadingPlugin(
isBuild: string,
env: Record<string, any>,
): Promise<PluginOption | undefined> {
const loadingHtml = await getLoadingRawByHtmlTemplate(); const loadingHtml = await getLoadingRawByHtmlTemplate();
const envRaw = isBuild ? 'prod' : 'dev';
const cacheName = `'__${env.VITE_APP_NAMESPACE}-${envRaw}-theme__'`;
// 获取缓存的主题
// 保证黑暗主题下刷新页面时loading也是黑暗主题
const injectScript = `
<script>
var theme = localStorage.getItem(${cacheName});
document.documentElement.classList.toggle('dark', theme === 'dark');
</script>
`;
if (!loadingHtml) { if (!loadingHtml) {
return; return;
@ -21,7 +35,10 @@ async function viteInjectAppLoadingPlugin(): Promise<PluginOption | undefined> {
transformIndexHtml: { transformIndexHtml: {
handler(html) { handler(html) {
const re = /<div\s*id\s*=\s*"app"\s*>(\s*)<\/div>/; const re = /<div\s*id\s*=\s*"app"\s*>(\s*)<\/div>/;
html = html.replace(re, `<div id="app">${loadingHtml}</div>`); html = html.replace(
re,
`<div id="app">${injectScript}${loadingHtml}</div>`,
);
return html; return html;
}, },
order: 'pre', order: 'pre',

View File

@ -5,7 +5,7 @@
} }
.dark .loading { .dark .loading {
background-color: #2c344a; background-color: #0d0d10;
} }
.dark .loading .title { .dark .loading .title {

View File

@ -18,7 +18,7 @@
} }
.dark .loading { .dark .loading {
background: #101827; background: #0d0d10;
} }
.title { .title {

View File

@ -39,6 +39,8 @@ interface ConditionPlugin {
interface CommonPluginOptions { interface CommonPluginOptions {
/** 是否开启devtools */ /** 是否开启devtools */
devtools?: boolean; devtools?: boolean;
/** 环境变量 */
env: Record<string, any>;
/** 是否构建模式 */ /** 是否构建模式 */
isBuild?: boolean; isBuild?: boolean;
/** 构建模式 */ /** 构建模式 */

View File

@ -4,10 +4,6 @@ import { PreferenceCache } from './cache';
import { overridesPreference } from './preference'; import { overridesPreference } from './preference';
interface SetupPreferenceOptions { interface SetupPreferenceOptions {
/**
* @zh_CN
*/
env: string;
/** /**
* @zh_CN , @vben/preference appapp * @zh_CN , @vben/preference appapp
* *
@ -20,8 +16,8 @@ interface SetupPreferenceOptions {
} }
async function setupPreference(options: SetupPreferenceOptions) { async function setupPreference(options: SetupPreferenceOptions) {
const { env, namespace, overrides = {} } = options; const { namespace, overrides = {} } = options;
const cache = new PreferenceCache(`${namespace}-${env}`); const cache = new PreferenceCache(namespace);
overridesPreference(overrides, cache); overridesPreference(overrides, cache);
} }

View File

@ -3,10 +3,6 @@ import type { App } from 'vue';
import { createPinia } from 'pinia'; import { createPinia } from 'pinia';
interface SetupStoreOptions { interface SetupStoreOptions {
/**
* @zh_CN
*/
env: string;
/** /**
* @zh_CN , @vben/stores appapp * @zh_CN , @vben/stores appapp
* *
@ -21,11 +17,11 @@ interface SetupStoreOptions {
async function setupStore(app: App, options: SetupStoreOptions) { async function setupStore(app: App, options: SetupStoreOptions) {
const { createPersistedState } = await import('pinia-plugin-persistedstate'); const { createPersistedState } = await import('pinia-plugin-persistedstate');
const pinia = createPinia(); const pinia = createPinia();
const { env, namespace } = options; const { namespace } = options;
pinia.use( pinia.use(
createPersistedState({ createPersistedState({
// key $appName-$store.id // key $appName-$store.id
key: (storeKey) => `__${namespace}-${env}-${storeKey}__`, key: (storeKey) => `__${namespace}-${storeKey}__`,
storage: localStorage, storage: localStorage,
}), }),
); );