refactor(layout): 重构基础布局头部组件结构

This commit is contained in:
严浩
2025-10-25 22:46:11 +08:00
parent cc49ce2beb
commit a1160bc394
10 changed files with 141 additions and 89 deletions

View File

@@ -0,0 +1,16 @@
<script setup lang="ts">
import LanguageSwitchButton from './components/LanguageSwitchButton.vue';
import ThemeSwitchButton from './components/ThemeSwitchButton.vue';
import ToggleSiderButton from './components/ToggleSiderButton.vue';
</script>
<template>
<div class="h-full flex items-center justify-between px-12px shadow-header dark:shadow-gray-700">
<ToggleSiderButton />
<div class="flex items-center">
<LanguageSwitchButton />
<ThemeSwitchButton />
</div>
</div>
</template>

View File

@@ -0,0 +1,33 @@
<script setup lang="ts">
import type { DropdownOption } from 'naive-ui';
const { locale, availableLocales } = useI18n({ useScope: 'global' });
const languageLabels: Record<string, string> = {
'en-US': 'English',
'zh-CN': '简体中文',
};
const options = computed<DropdownOption[]>(() =>
availableLocales.map((lang) => ({
label: languageLabels[lang] || lang,
key: lang,
disabled: locale.value === lang,
})),
);
function handleSelect(key: string) {
locale.value = key;
}
</script>
<template>
<NDropdown trigger="hover" placement="bottom-end" :options="options" @select="handleSelect">
<NButton quaternary class="flex items-center gap-1">
<template #icon>
<icon-clarity:language-line w-4.5 h-4.5 />
</template>
<span>{{ languageLabels[locale] }}</span>
</NButton>
</NDropdown>
</template>

View File

@@ -0,0 +1,30 @@
<script setup lang="ts">
const appStore = useAppStore();
const themeLabels: Record<AppThemeMode, string> = {
light: '浅色',
dark: '深色',
system: '跟随系统',
};
</script>
<template>
<NTooltip :disabled="appStore.isMobile" placement="bottom-end">
{{ themeLabels[appStore.themeMode] }}
<template #trigger>
<NButton quaternary @click="appStore.cycleTheme">
<icon-line-md:sunny-filled-loop-to-moon-filled-loop-transition
v-if="appStore.themeMode === 'light'"
w-4.5
h-4.5
/>
<icon-line-md:moon-filled-to-sunny-filled-loop-transition
v-else-if="appStore.themeMode === 'dark'"
w-4.5
h-4.5
/>
<icon-line-md:computer v-else w-4.5 h-4.5 />
</NButton>
</template>
</NTooltip>
</template>

View File

@@ -0,0 +1,23 @@
<script setup lang="ts">
const buttonRef = useTemplateRef('buttonRef');
const appStore = useAppStore();
function toggleCollapsed() {
// https://github.com/tusen-ai/naive-ui/issues/3688
// hover style 鼠标移出就会消失 如果是点击 button 会聚焦需要失去焦点才会恢复
buttonRef.value?.$el.blur();
appStore.toggleSidebar();
}
</script>
<template>
<NTooltip :disabled="appStore.isMobile" placement="bottom-start">
{{ appStore.sidebarCollapsed ? '展开菜单' : '收起菜单' }}
<template #trigger>
<NButton ref="buttonRef" quaternary @click="toggleCollapsed">
<icon-line-md:menu-fold-right v-if="appStore.sidebarCollapsed" w-4.5 h-4.5 />
<icon-line-md:menu-fold-left v-else w-4.5 h-4.5 />
</NButton>
</template>
</NTooltip>
</template>