Skip to content

Commit a1d3268

Browse files
committed
feat: 将账号信息按钮封装为 AccountButton 组件,并优化工具栏和导航栏的显示逻辑
1 parent 3be15b2 commit a1d3268

File tree

9 files changed

+55
-24
lines changed

9 files changed

+55
-24
lines changed
Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,23 @@
11
<script setup lang="ts">
2+
import type { HTMLAttributes } from 'vue'
23
import useSettingsStore from '@/store/modules/settings'
34
import useUserStore from '@/store/modules/user'
5+
import { cn } from '@/utils'
46
import eventBus from '@/utils/eventBus'
57
import Profile from './profile.vue'
68
9+
const props = withDefaults(defineProps<{
10+
onlyAvatar?: boolean
11+
dropdownAlign?: 'start' | 'center' | 'end'
12+
dropdownSide?: 'left' | 'right' | 'top' | 'bottom'
13+
buttonVariant?: 'secondary' | 'ghost'
14+
class?: HTMLAttributes['class']
15+
}>(), {
16+
dropdownAlign: 'end',
17+
dropdownSide: 'right',
18+
buttonVariant: 'ghost',
19+
})
20+
721
const router = useRouter()
822
923
const settingsStore = useSettingsStore()
@@ -14,7 +28,7 @@ const isProfileShow = ref(false)
1428

1529
<template>
1630
<FaDropdown
17-
align="end" :items="[
31+
:align="dropdownAlign" :side="dropdownSide" :items="[
1832
[
1933
{ label: settingsStore.settings.home.title, icon: 'i-mdi:home', handle: () => router.push({ path: settingsStore.settings.home.fullPath }), hide: !settingsStore.settings.home.enable },
2034
{ label: '个人设置', icon: 'i-mdi:account', handle: () => isProfileShow = true },
@@ -39,20 +53,26 @@ const isProfileShow = ref(false)
3953
{{ userStore.account }}
4054
</div>
4155
<div class="text-xs text-secondary-foreground/50 font-normal">
42-
这里可以显示邮箱
56+
[ 这里可以显示邮箱 ]
4357
</div>
4458
</div>
4559
</div>
4660
</div>
4761
</template>
48-
<FaButton variant="ghost" class="h-9 flex-center gap-1 px-2">
49-
<FaAvatar :src="userStore.avatar" class="size-6">
50-
<FaIcon name="i-carbon:user-avatar-filled-alt" class="size-6 text-secondary-foreground/50" />
62+
<FaButton
63+
:variant="buttonVariant" :class="cn('flex-center gap-1 p-2', {
64+
'size-8 p-1': onlyAvatar,
65+
}, props.class)"
66+
>
67+
<FaAvatar :src="userStore.avatar" :class="cn('size-6', { 'size-full': onlyAvatar })">
68+
<FaIcon name="i-carbon:user-avatar-filled" class="size-6 text-secondary-foreground/50" />
5169
</FaAvatar>
52-
<template v-if="settingsStore.mode === 'pc'">
53-
{{ userStore.account }}
54-
<FaIcon name="i-ep:caret-bottom" />
55-
</template>
70+
<div v-if="settingsStore.mode === 'pc' && !onlyAvatar" class="min-w-0 flex-center-between flex-1 gap-2">
71+
<div class="flex-1 truncate text-start">
72+
{{ userStore.account }}
73+
</div>
74+
<FaIcon name="i-material-symbols:expand-all-rounded" />
75+
</div>
5676
</FaButton>
5777
</FaDropdown>
5878
<FaModal v-model="isProfileShow" align-center :header="false" :footer="false" :close-on-click-overlay="false" :close-on-press-escape="false" class="h-500px min-w-600px overflow-hidden" content-class="min-h-full p-0 flex">

src/layouts/components/Header/index.vue

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { useSlots } from '@/slots'
33
import useMenuStore from '@/store/modules/menu'
44
import useSettingsStore from '@/store/modules/settings'
55
import Logo from '../Logo/index.vue'
6-
import ToolbarRightSide from '../Topbar/Toolbar/rightSide.vue'
76
87
defineOptions({
98
name: 'LayoutHeader',
@@ -18,8 +17,8 @@ const { switchTo } = useMenu()
1817
<template>
1918
<Transition name="header">
2019
<header v-if="settingsStore.mode === 'pc' && settingsStore.settings.menu.mode === 'head'">
21-
<component :is="useSlots('header-start')" />
2220
<div class="header-container">
21+
<component :is="useSlots('header-start')" />
2322
<Logo class="title" />
2423
<component :is="useSlots('header-after-logo')" />
2524
<FaScrollArea :scrollbar="false" mask horizontal gradient-color="var(--g-header-bg)" class="menu-container h-full flex-1">
@@ -47,9 +46,11 @@ const { switchTo } = useMenu()
4746
</template>
4847
</div>
4948
</FaScrollArea>
50-
<ToolbarRightSide />
49+
<div class="flex-center">
50+
<AccountButton only-avatar dropdown-side="bottom" class="size-12 p-2" />
51+
</div>
52+
<component :is="useSlots('header-end')" />
5153
</div>
52-
<component :is="useSlots('header-end')" />
5354
</header>
5455
</Transition>
5556
</template>
@@ -78,7 +79,7 @@ header {
7879
justify-content: space-between;
7980
width: 100%;
8081
height: 100%;
81-
padding: 0 12px 0 20px;
82+
padding: 0 12px;
8283
margin: 0 auto;
8384
8485
:deep(a.title) {

src/layouts/components/MainSidebar/index.vue

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ onUnmounted(() => {
6565
</template>
6666
</div>
6767
</FaScrollArea>
68+
<div class="flex-center px-4 py-3">
69+
<AccountButton only-avatar :button-variant="settingsStore.settings.menu.mode === 'side' ? 'secondary' : 'ghost'" class="size-12 p-2" />
70+
</div>
6871
<component :is="useSlots('main-sidebar-bottom')" />
6972
</div>
7073
</Transition>

src/layouts/components/SubSidebar/index.vue

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ watch(() => menuStore.actived, (val, oldVal) => {
7474
<FaIcon name="toolbar-collapse" class="size-4" />
7575
</FaButton>
7676
</div>
77+
<div v-if="settingsStore.settings.menu.mode === 'single'" class="flex-center px-4 pb-3">
78+
<AccountButton :only-avatar="settingsStore.settings.menu.subMenuCollapse" dropdown-align="center" :dropdown-side="settingsStore.settings.menu.subMenuCollapse ? 'right' : 'top'" button-variant="secondary" :class="{ 'w-full': !settingsStore.settings.menu.subMenuCollapse }" />
79+
</div>
7780
<component :is="useSlots('sub-sidebar-bottom')" />
7881
</div>
7982
</Transition>

src/layouts/components/Topbar/Toolbar/index.vue

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,18 @@
11
<script setup lang="ts">
2-
import useSettingsStore from '@/store/modules/settings'
32
import LeftSide from './leftSide.vue'
43
import RightSide from './rightSide.vue'
54
65
defineOptions({
76
name: 'Toolbar',
87
})
9-
10-
const settingsStore = useSettingsStore()
118
</script>
129

1310
<template>
1411
<div class="toolbar-container flex items-center justify-between">
1512
<div class="left-side h-full flex items-center of-hidden pe-16 ps-2">
1613
<LeftSide />
1714
</div>
18-
<div v-if="['side', 'single'].includes(settingsStore.settings.menu.mode) || settingsStore.mode === 'mobile'" class="h-full flex flex-shrink-0 items-center justify-end px-2">
15+
<div class="h-full flex flex-shrink-0 items-center justify-end px-2">
1916
<RightSide />
2017
</div>
2118
</div>

src/layouts/components/Topbar/index.vue

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@ defineOptions({
1010
const settingsStore = useSettingsStore()
1111
1212
const enableToolbar = computed(() => {
13-
return !(
14-
settingsStore.settings.menu.mode === 'head' && (
15-
!settingsStore.settings.toolbar.breadcrumb || settingsStore.settings.app.routeBaseOn === 'filesystem'
16-
)
17-
)
13+
return Object.keys(settingsStore.settings.toolbar).some((key) => {
14+
if (settingsStore.settings.app.routeBaseOn === 'filesystem' && key === 'breadcrumb') {
15+
return false
16+
}
17+
return settingsStore.settings.toolbar[key as keyof typeof settingsStore.settings.toolbar]
18+
})
1819
})
1920
2021
const scrollTop = ref(0)

src/layouts/index.vue

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,12 @@ const topbarActualHeight = computed(() => {
5858
if (settingsStore.settings.tabbar.enable) {
5959
actualHeight += Number.parseInt(getComputedStyle(document.documentElement).getPropertyValue('--g-tabbar-height'))
6060
}
61-
if (!['head'].includes(settingsStore.settings.menu.mode) || settingsStore.settings.toolbar.breadcrumb) {
61+
if (Object.keys(settingsStore.settings.toolbar).some((key) => {
62+
if (settingsStore.settings.app.routeBaseOn === 'filesystem' && key === 'breadcrumb') {
63+
return false
64+
}
65+
return settingsStore.settings.toolbar[key as keyof typeof settingsStore.settings.toolbar]
66+
})) {
6267
actualHeight += Number.parseInt(getComputedStyle(document.documentElement).getPropertyValue('--g-toolbar-height'))
6368
}
6469
return actualHeight

src/types/components.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export {}
88
/* prettier-ignore */
99
declare module 'vue' {
1010
export interface GlobalComponents {
11+
AccountButton: typeof import('./../components/AccountButton/index.vue')['default']
1112
FaAuth: typeof import('./../ui/components/FaAuth/index.vue')['default']
1213
FaAvatar: typeof import('./../ui/components/FaAvatar/index.vue')['default']
1314
FaBackToTop: typeof import('./../ui/components/FaBackToTop/index.vue')['default']

0 commit comments

Comments
 (0)