fix: When refreshing the page, the topic is wrong
parent
352119cc3a
commit
f2644dbbc5
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -8,8 +8,22 @@ import { type PluginOption } from 'vite';
|
||||||
* 用于生成将loading样式注入到项目中
|
* 用于生成将loading样式注入到项目中
|
||||||
* 为多app提供loading样式,无需在每个 app -> index.html单独引入
|
* 为多app提供loading样式,无需在每个 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',
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark .loading {
|
.dark .loading {
|
||||||
background-color: #2c344a;
|
background-color: #0d0d10;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark .loading .title {
|
.dark .loading .title {
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark .loading {
|
.dark .loading {
|
||||||
background: #101827;
|
background: #0d0d10;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
|
|
|
@ -39,6 +39,8 @@ interface ConditionPlugin {
|
||||||
interface CommonPluginOptions {
|
interface CommonPluginOptions {
|
||||||
/** 是否开启devtools */
|
/** 是否开启devtools */
|
||||||
devtools?: boolean;
|
devtools?: boolean;
|
||||||
|
/** 环境变量 */
|
||||||
|
env: Record<string, any>;
|
||||||
/** 是否构建模式 */
|
/** 是否构建模式 */
|
||||||
isBuild?: boolean;
|
isBuild?: boolean;
|
||||||
/** 构建模式 */
|
/** 构建模式 */
|
||||||
|
|
|
@ -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 是公用的,后续可能有多个app,为了防止多个app缓存冲突,可在这里配置应用名
|
* @zh_CN 应用名,由于 @vben/preference 是公用的,后续可能有多个app,为了防止多个app缓存冲突,可在这里配置应用名
|
||||||
* 应用名将被用于持久化的前缀
|
* 应用名将被用于持久化的前缀
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 是公用的,后续可能有多个app,为了防止多个app缓存冲突,可在这里配置应用名
|
* @zh_CN 应用名,由于 @vben/stores 是公用的,后续可能有多个app,为了防止多个app缓存冲突,可在这里配置应用名
|
||||||
* 应用名将被用于持久化的前缀
|
* 应用名将被用于持久化的前缀
|
||||||
|
@ -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,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue