feat(project): support dynamic title
parent
e83adf0697
commit
d1cdea430e
|
@ -35,6 +35,7 @@
|
||||||
"@vben/styles": "workspace:*",
|
"@vben/styles": "workspace:*",
|
||||||
"@vben/types": "workspace:*",
|
"@vben/types": "workspace:*",
|
||||||
"@vben/utils": "workspace:*",
|
"@vben/utils": "workspace:*",
|
||||||
|
"@vueuse/core": "^10.9.0",
|
||||||
"ant-design-vue": "^4.2.1",
|
"ant-design-vue": "^4.2.1",
|
||||||
"axios": "^1.7.1",
|
"axios": "^1.7.1",
|
||||||
"dayjs": "^1.11.11",
|
"dayjs": "^1.11.11",
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import type { Router } from 'vue-router';
|
import type { Router } from 'vue-router';
|
||||||
|
|
||||||
|
import { $t } from '@vben/locales';
|
||||||
import { preference } from '@vben/preference';
|
import { preference } from '@vben/preference';
|
||||||
import { startProgress, stopProgress } from '@vben/utils';
|
import { startProgress, stopProgress } from '@vben/utils';
|
||||||
|
import { useTitle } from '@vueuse/core';
|
||||||
|
|
||||||
import { configAccessGuard } from './access';
|
import { configAccessGuard } from './access';
|
||||||
|
|
||||||
|
@ -26,6 +28,12 @@ function configCommonGuard(router: Router) {
|
||||||
if (preference.pageProgress) {
|
if (preference.pageProgress) {
|
||||||
stopProgress();
|
stopProgress();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 动态修改标题
|
||||||
|
if (preference.dynamicTitle) {
|
||||||
|
const { title } = to.meta;
|
||||||
|
useTitle(`${$t(title)} - ${preference.appName}`);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ export default defineConfig({
|
||||||
{ name: 'vue-demi' },
|
{ name: 'vue-demi' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
visualizer: true,
|
visualizer: false,
|
||||||
},
|
},
|
||||||
vite: {
|
vite: {
|
||||||
server: {
|
server: {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
.dark {
|
:root.dark {
|
||||||
/* 基础背景颜色颜色 */
|
/* 基础背景颜色颜色 */
|
||||||
|
|
||||||
/* --color-background: 240 6% 18%; */
|
/* --color-background: 240 6% 18%; */
|
||||||
|
|
|
@ -55,6 +55,8 @@ interface Preference {
|
||||||
copyright: string;
|
copyright: string;
|
||||||
/** 应用默认头像 */
|
/** 应用默认头像 */
|
||||||
defaultAvatar: string;
|
defaultAvatar: string;
|
||||||
|
/** 开启动态标题 */
|
||||||
|
dynamicTitle: boolean;
|
||||||
/** 页脚是否固定 */
|
/** 页脚是否固定 */
|
||||||
footerFixed: boolean;
|
footerFixed: boolean;
|
||||||
/** 页脚是否可见 */
|
/** 页脚是否可见 */
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { type ComputedRef, type MaybeRef } from 'vue';
|
import { type ComputedRef, type MaybeRef } from 'vue';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 深度部分类型
|
* 深层递归所有属性为可选
|
||||||
*/
|
*/
|
||||||
type DeepPartial<T> = T extends object
|
type DeepPartial<T> = T extends object
|
||||||
? {
|
? {
|
||||||
|
@ -9,6 +9,13 @@ type DeepPartial<T> = T extends object
|
||||||
}
|
}
|
||||||
: T;
|
: T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 深层递归所有属性为只读
|
||||||
|
*/
|
||||||
|
type DeepReadonly<T> = {
|
||||||
|
readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P];
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 任意类型的异步函数
|
* 任意类型的异步函数
|
||||||
*/
|
*/
|
||||||
|
@ -78,6 +85,7 @@ export {
|
||||||
type AnyNormalFunction,
|
type AnyNormalFunction,
|
||||||
type AnyPromiseFunction,
|
type AnyPromiseFunction,
|
||||||
type DeepPartial,
|
type DeepPartial,
|
||||||
|
type DeepReadonly,
|
||||||
type IntervalHandle,
|
type IntervalHandle,
|
||||||
type MaybeComputedRef,
|
type MaybeComputedRef,
|
||||||
type MaybeReadonlyRef,
|
type MaybeReadonlyRef,
|
||||||
|
|
|
@ -69,6 +69,7 @@ const logoClass = computed(() => {
|
||||||
/>
|
/>
|
||||||
<span v-if="!collapse" class="truncate text-nowrap">
|
<span v-if="!collapse" class="truncate text-nowrap">
|
||||||
{{ text }}
|
{{ text }}
|
||||||
|
<!-- <span class="text-primary ml-1 align-super text-[smaller]">Pro</span> -->
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -42,6 +42,9 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@vben-core/design": "workspace:*"
|
||||||
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vben-core/design": "workspace:*",
|
"@vben-core/design": "workspace:*",
|
||||||
"@vben-core/iconify": "workspace:*",
|
"@vben-core/iconify": "workspace:*",
|
||||||
|
|
|
@ -5,12 +5,14 @@ import { $t } from '@vben/locales';
|
||||||
import { staticPreference } from '@vben/preference';
|
import { staticPreference } from '@vben/preference';
|
||||||
|
|
||||||
import SelectItem from '../select-item.vue';
|
import SelectItem from '../select-item.vue';
|
||||||
|
import SwitchItem from '../switch-item.vue';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'PreferenceGeneralConfig',
|
name: 'PreferenceGeneralConfig',
|
||||||
});
|
});
|
||||||
|
|
||||||
const locale = defineModel<string>('locale');
|
const locale = defineModel<string>('locale');
|
||||||
|
const dynamicTitle = defineModel<boolean>('dynamicTitle');
|
||||||
|
|
||||||
const localeItems: SelectListItem[] = staticPreference.supportLanguages.map(
|
const localeItems: SelectListItem[] = staticPreference.supportLanguages.map(
|
||||||
(item) => ({
|
(item) => ({
|
||||||
|
@ -24,4 +26,7 @@ const localeItems: SelectListItem[] = staticPreference.supportLanguages.map(
|
||||||
<SelectItem v-model="locale" :items="localeItems">
|
<SelectItem v-model="locale" :items="localeItems">
|
||||||
{{ $t('preference.language') }}
|
{{ $t('preference.language') }}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
|
<SwitchItem v-model="dynamicTitle">
|
||||||
|
{{ $t('preference.dynamic-title') }}
|
||||||
|
</SwitchItem>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -46,6 +46,7 @@ function updateLocale(value: string) {
|
||||||
:footer-fixed="preference.footerFixed"
|
:footer-fixed="preference.footerFixed"
|
||||||
:header-mode="preference.headerMode"
|
:header-mode="preference.headerMode"
|
||||||
:theme="preference.theme"
|
:theme="preference.theme"
|
||||||
|
:dynamic-title="preference.dynamicTitle"
|
||||||
:breadcrumb-hide-only-one="preference.breadcrumbHideOnlyOne"
|
:breadcrumb-hide-only-one="preference.breadcrumbHideOnlyOne"
|
||||||
:page-transition="preference.pageTransition"
|
:page-transition="preference.pageTransition"
|
||||||
:page-progress="preference.pageProgress"
|
:page-progress="preference.pageProgress"
|
||||||
|
@ -55,6 +56,7 @@ function updateLocale(value: string) {
|
||||||
:side-collapse-show-title="preference.sideCollapseShowTitle"
|
:side-collapse-show-title="preference.sideCollapseShowTitle"
|
||||||
:page-transition-enable="preference.pageTransitionEnable"
|
:page-transition-enable="preference.pageTransitionEnable"
|
||||||
@update:navigation-style="(value) => handleUpdate('navigationStyle', value)"
|
@update:navigation-style="(value) => handleUpdate('navigationStyle', value)"
|
||||||
|
@update:dynamic-title="(value) => handleUpdate('dynamicTitle', value)"
|
||||||
@update:tabs-icon="(value) => handleUpdate('tabsIcon', value)"
|
@update:tabs-icon="(value) => handleUpdate('tabsIcon', value)"
|
||||||
@update:side-collapse="(value) => handleUpdate('sideCollapse', value)"
|
@update:side-collapse="(value) => handleUpdate('sideCollapse', value)"
|
||||||
@update:locale="updateLocale"
|
@update:locale="updateLocale"
|
||||||
|
|
|
@ -40,6 +40,7 @@ withDefaults(defineProps<{ colorPrimaryPresets: string[] }>(), {
|
||||||
|
|
||||||
const theme = defineModel<string>('theme');
|
const theme = defineModel<string>('theme');
|
||||||
const locale = defineModel<string>('locale');
|
const locale = defineModel<string>('locale');
|
||||||
|
const dynamicTitle = defineModel<boolean>('dynamicTitle');
|
||||||
const semiDarkMenu = defineModel<boolean>('semiDarkMenu');
|
const semiDarkMenu = defineModel<boolean>('semiDarkMenu');
|
||||||
const breadcrumbVisible = defineModel<boolean>('breadcrumbVisible');
|
const breadcrumbVisible = defineModel<boolean>('breadcrumbVisible');
|
||||||
const breadcrumbIcon = defineModel<boolean>('breadcrumbIcon');
|
const breadcrumbIcon = defineModel<boolean>('breadcrumbIcon');
|
||||||
|
@ -210,7 +211,10 @@ function handleReset() {
|
||||||
</template>
|
</template>
|
||||||
<template #general>
|
<template #general>
|
||||||
<Block :title="$t('preference.general')">
|
<Block :title="$t('preference.general')">
|
||||||
<General v-model:locale="locale" />
|
<General
|
||||||
|
v-model:locale="locale"
|
||||||
|
v-model:dynamic-title="dynamicTitle"
|
||||||
|
/>
|
||||||
</Block>
|
</Block>
|
||||||
<Block :title="$t('preference.navigation-menu')">
|
<Block :title="$t('preference.navigation-menu')">
|
||||||
<Navigation
|
<Navigation
|
||||||
|
|
|
@ -69,6 +69,7 @@ preference:
|
||||||
gray-mode: Gray Mode
|
gray-mode: Gray Mode
|
||||||
animation: Animation
|
animation: Animation
|
||||||
language: Language
|
language: Language
|
||||||
|
dynamic-title: Dynamic Title
|
||||||
normal: Normal
|
normal: Normal
|
||||||
rounded: Rounded
|
rounded: Rounded
|
||||||
collapse: Collpase Menu
|
collapse: Collpase Menu
|
||||||
|
|
|
@ -51,6 +51,7 @@ preference:
|
||||||
dark: 深色
|
dark: 深色
|
||||||
dark-menu: 深色菜单
|
dark-menu: 深色菜单
|
||||||
language: 语言
|
language: 语言
|
||||||
|
dynamic-title: 动态标题
|
||||||
collapse: 折叠菜单
|
collapse: 折叠菜单
|
||||||
collapse-show-title: 显示菜单名
|
collapse-show-title: 显示菜单名
|
||||||
wide: 流式
|
wide: 流式
|
||||||
|
|
|
@ -16,6 +16,7 @@ const defaultPreference: Preference = {
|
||||||
copyright: 'Copyright © 2024 Vben Admin PRO',
|
copyright: 'Copyright © 2024 Vben Admin PRO',
|
||||||
defaultAvatar:
|
defaultAvatar:
|
||||||
'https://cdn.jsdelivr.net/gh/vbenjs/vben-cdn-static@0.1.2/vben-admin/pro-avatar.webp',
|
'https://cdn.jsdelivr.net/gh/vbenjs/vben-cdn-static@0.1.2/vben-admin/pro-avatar.webp',
|
||||||
|
dynamicTitle: true,
|
||||||
footerFixed: true,
|
footerFixed: true,
|
||||||
footerVisible: true,
|
footerVisible: true,
|
||||||
headerMode: 'fixed',
|
headerMode: 'fixed',
|
||||||
|
|
|
@ -126,6 +126,9 @@ importers:
|
||||||
'@vben/utils':
|
'@vben/utils':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../packages/utils
|
version: link:../../packages/utils
|
||||||
|
'@vueuse/core':
|
||||||
|
specifier: ^10.9.0
|
||||||
|
version: 10.9.0(vue@3.4.27(typescript@5.4.5))
|
||||||
ant-design-vue:
|
ant-design-vue:
|
||||||
specifier: ^4.2.1
|
specifier: ^4.2.1
|
||||||
version: 4.2.1(vue@3.4.27(typescript@5.4.5))
|
version: 4.2.1(vue@3.4.27(typescript@5.4.5))
|
||||||
|
|
Loading…
Reference in New Issue