|
1 | 1 | <script setup> |
2 | | -import { onMounted, ref, h, watch } from 'vue'; |
3 | | -import { ConfigProvider, Layout, Menu } from 'ant-design-vue'; |
| 2 | +import { onMounted, ref, h, watch, computed } from 'vue'; |
| 3 | +import { ConfigProvider, Layout, Menu, theme as antTheme } from 'ant-design-vue'; |
4 | 4 | import { FileTextOutlined, SettingOutlined } from '@ant-design/icons-vue'; |
5 | 5 | import HomeView from './components/HomeView.vue'; |
6 | 6 | import ConfigView from './components/ConfigView.vue'; |
7 | 7 | import { useCommitTypesStore } from './stores/commitTypes'; |
| 8 | +import { useSettingsStore } from './stores/settings'; |
8 | 9 |
|
9 | 10 | const { Sider, Content } = Layout; |
10 | 11 |
|
11 | 12 | const currentView = ref(['home']); |
12 | 13 | const enterAction = ref({}); |
13 | 14 | const commitTypesStore = useCommitTypesStore(); |
| 15 | +const settingsStore = useSettingsStore(); |
| 16 | +
|
| 17 | +// 主题相关 |
| 18 | +const systemDarkMode = ref(window.matchMedia('(prefers-color-scheme: dark)').matches); |
| 19 | +
|
| 20 | +// 计算实际使用的主题 |
| 21 | +const actualTheme = computed(() => { |
| 22 | + if (settingsStore.theme === 'system') { |
| 23 | + return systemDarkMode.value ? 'dark' : 'light'; |
| 24 | + } |
| 25 | + return settingsStore.theme; |
| 26 | +}); |
| 27 | +
|
| 28 | +// Ant Design 主题配置 |
| 29 | +const themeConfig = computed(() => { |
| 30 | + return { |
| 31 | + algorithm: actualTheme.value === 'dark' ? antTheme.darkAlgorithm : antTheme.defaultAlgorithm |
| 32 | + }; |
| 33 | +}); |
| 34 | +
|
| 35 | +// 应用主题到document |
| 36 | +const applyTheme = () => { |
| 37 | + document.documentElement.setAttribute('data-theme', actualTheme.value); |
| 38 | +}; |
14 | 39 |
|
15 | 40 | const menuItems = [ |
16 | 41 | { |
@@ -68,6 +93,16 @@ const registerCommands = () => { |
68 | 93 | }; |
69 | 94 |
|
70 | 95 | onMounted(() => { |
| 96 | + // 应用初始主题 |
| 97 | + applyTheme(); |
| 98 | +
|
| 99 | + // 监听系统主题变化 |
| 100 | + const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); |
| 101 | + const handleThemeChange = (e) => { |
| 102 | + systemDarkMode.value = e.matches; |
| 103 | + }; |
| 104 | + darkModeMediaQuery.addEventListener('change', handleThemeChange); |
| 105 | +
|
71 | 106 | // 清理可能存在的旧动态功能 |
72 | 107 | try { |
73 | 108 | const existingFeatures = window.utools.getFeatures(); |
@@ -108,18 +143,25 @@ watch( |
108 | 143 | } |
109 | 144 | ); |
110 | 145 |
|
| 146 | +// 监听主题变化 |
| 147 | +watch(actualTheme, () => { |
| 148 | + applyTheme(); |
| 149 | +}); |
| 150 | +
|
111 | 151 | const handleMenuClick = ({ key }) => { |
112 | 152 | currentView.value = [key]; |
113 | 153 | }; |
114 | 154 | </script> |
115 | 155 |
|
116 | 156 | <template> |
117 | | - <ConfigProvider> |
| 157 | + <ConfigProvider :theme="themeConfig"> |
118 | 158 | <Layout style="min-height: 100vh;"> |
119 | | - <Sider theme="light" :width="150" style="border-right: 1px solid #f0f0f0;"> |
120 | | - <Menu v-model:selectedKeys="currentView" mode="inline" :items="menuItems" @click="handleMenuClick" /> |
| 159 | + <Sider :theme="actualTheme === 'dark' ? 'dark' : 'light'" :width="150" |
| 160 | + :style="{ borderRight: actualTheme === 'dark' ? '1px solid #303030' : '1px solid #f0f0f0' }"> |
| 161 | + <Menu style="height: 100%;" v-model:selectedKeys="currentView" mode="inline" :items="menuItems" |
| 162 | + @click="handleMenuClick" /> |
121 | 163 | </Sider> |
122 | | - <Content style="background: #fff;"> |
| 164 | + <Content :style="{ background: actualTheme === 'dark' ? '#141414' : '#fff' }"> |
123 | 165 | <HomeView v-if="currentView[0] === 'home'" :enterAction="enterAction" /> |
124 | 166 | <ConfigView v-else-if="currentView[0] === 'config'" /> |
125 | 167 | </Content> |
|
0 commit comments