feat(project): support dynamic title

pull/48/MERGE
vben 2024-05-22 22:03:41 +08:00
parent e83adf0697
commit d1cdea430e
15 changed files with 44 additions and 4 deletions

View File

@ -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",

View File

@ -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}`);
}
}); });
} }

View File

@ -18,7 +18,7 @@ export default defineConfig({
{ name: 'vue-demi' }, { name: 'vue-demi' },
], ],
}, },
visualizer: true, visualizer: false,
}, },
vite: { vite: {
server: { server: {

View File

@ -1,4 +1,4 @@
.dark { :root.dark {
/* 基础背景颜色颜色 */ /* 基础背景颜色颜色 */
/* --color-background: 240 6% 18%; */ /* --color-background: 240 6% 18%; */

View File

@ -55,6 +55,8 @@ interface Preference {
copyright: string; copyright: string;
/** 应用默认头像 */ /** 应用默认头像 */
defaultAvatar: string; defaultAvatar: string;
/** 开启动态标题 */
dynamicTitle: boolean;
/** 页脚是否固定 */ /** 页脚是否固定 */
footerFixed: boolean; footerFixed: boolean;
/** 页脚是否可见 */ /** 页脚是否可见 */

View File

@ -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,

View File

@ -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>

View File

@ -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:*",

View File

@ -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>

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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: 流式

View File

@ -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',

View File

@ -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))