89 lines
1.9 KiB
Vue
89 lines
1.9 KiB
Vue
<template>
|
|
<div>
|
|
<h4>主题</h4>
|
|
<div class="theme-grid">
|
|
<div
|
|
v-for="(theme, name) in filteredThemes"
|
|
:key="name"
|
|
class="theme-option"
|
|
:class="{ 'active': currentTheme === name }"
|
|
@click="changeTheme(name)"
|
|
>
|
|
<div class="theme-preview" :style="{ backgroundColor: theme.primary }"></div>
|
|
<span class="theme-label">{{ getThemeLabel(name) }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, computed } from 'vue';
|
|
import { useSettingsStore } from '@/store/settings';
|
|
import { themes as availableThemes } from '@/styles/theme';
|
|
|
|
const settingsStore = useSettingsStore();
|
|
const currentTheme = ref(settingsStore.theme);
|
|
|
|
const filteredThemes = computed(() => {
|
|
const { dark, ...rest } = availableThemes;
|
|
return rest;
|
|
});
|
|
|
|
const themeLabels = {
|
|
default: '默认',
|
|
fresh: '清新',
|
|
classic: '经典',
|
|
warm: '暖色',
|
|
business: '商务',
|
|
gray: '灰色',
|
|
};
|
|
|
|
const getThemeLabel = (themeName) => {
|
|
return themeLabels[themeName] || themeName;
|
|
};
|
|
|
|
const changeTheme = (newTheme) => {
|
|
settingsStore.updateTheme(newTheme);
|
|
currentTheme.value = newTheme;
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.theme-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fill, minmax(60px, 1fr));
|
|
gap: 10px;
|
|
margin-bottom: 5px;
|
|
}
|
|
|
|
.theme-option {
|
|
cursor: pointer;
|
|
border: 2px solid transparent;
|
|
padding: 4px;
|
|
border-radius: 6px;
|
|
text-align: center;
|
|
transition: border-color 0.2s ease-in-out;
|
|
|
|
&:hover {
|
|
border-color: var(--el-border-color-hover);
|
|
}
|
|
|
|
&.active {
|
|
border-color: var(--el-color-primary);
|
|
}
|
|
|
|
.theme-preview {
|
|
width: 100%;
|
|
height: 30px;
|
|
border-radius: 4px;
|
|
margin-bottom: 5px;
|
|
border: 1px solid var(--el-border-color-lighter);
|
|
}
|
|
|
|
.theme-label {
|
|
font-size: 12px;
|
|
color: var(--el-text-color-regular);
|
|
display: block;
|
|
}
|
|
}
|
|
</style> |