feat(projects): 添加缓存主题色

This commit is contained in:
Soybean 2022-01-22 00:48:17 +08:00
parent 1d63a83822
commit 37092974d3
15 changed files with 87 additions and 34 deletions

View File

@ -12,8 +12,7 @@ const routes: AuthRoute.Route[] = [
component: 'self',
meta: {
title: '分析页',
requiresAuth: true,
keepAlive: true
requiresAuth: true
}
},
{
@ -98,7 +97,6 @@ const routes: AuthRoute.Route[] = [
title: '关于',
requiresAuth: true,
singleLayout: 'basic',
keepAlive: true,
permissions: ['super', 'admin', 'test'],
icon: 'fluent:book-information-24-regular',
order: 7

View File

@ -34,8 +34,8 @@ function initSvgLogo(id) {
function addThemeColorCssVars() {
const key = '__THEME_COLOR__';
const themeColor = '#1890ff';
const cssVars = window.localStorage.getItem(key) || `--primary-color: ${themeColor}`;
const themeColor = window.localStorage.getItem(key) || '#1890ff';
const cssVars = `--primary-color: ${themeColor}`;
document.documentElement.style.cssText = cssVars;
}

View File

@ -13,6 +13,8 @@ export interface ThemeSetting {
themeColorList: string[];
/** 其他颜色 */
otherColor: ThemeOtherColor;
/** 是否自定义info的颜色(默认取比主题色深一级的颜色) */
isCustomizeInfoColor: boolean;
/** 固定头部和多页签 */
fixedHeaderAndTab: boolean;
/** 显示重载按钮 */

View File

@ -1,6 +1,7 @@
<template>
<soybean-layout
:mode="mode"
:min-width="theme.layout.minWidth"
:fixed-header-and-tab="theme.fixedHeaderAndTab"
:header-height="theme.header.height"
:tab-visible="theme.tab.visible"

View File

@ -5,13 +5,17 @@
<color-checkbox :color="color" :checked="color === theme.themeColor" @click="theme.setThemeColor(color)" />
</n-grid-item>
</n-grid>
<n-button :block="true" :type="otherColorBtnType" class="mt-12px" @click="openModal">更多颜色</n-button>
<n-space :vertical="true" class="pt-12px">
<n-color-picker :value="theme.themeColor" :show-alpha="false" @update-value="theme.setThemeColor" />
<n-button :block="true" :type="otherColorBtnType" @click="openModal">更多颜色</n-button>
</n-space>
<color-modal :visible="visible" @close="closeModal" />
</template>
<script setup lang="ts">
import { computed } from 'vue';
import { NDivider, NGrid, NGridItem, NButton } from 'naive-ui';
import { NDivider, NGrid, NGridItem, NSpace, NButton, NColorPicker } from 'naive-ui';
import { isInTraditionColors } from '@/settings';
import { useThemeStore } from '@/store';
import { useBoolean } from '@/hooks';
import { ColorCheckbox, ColorModal } from './components';
@ -20,7 +24,7 @@ const theme = useThemeStore();
const { bool: visible, setTrue: openModal, setFalse: closeModal } = useBoolean();
const isInOther = computed(() => !theme.themeColorList.includes(theme.themeColor));
const isInOther = computed(() => isInTraditionColors(theme.themeColor));
const otherColorBtnType = computed(() => (isInOther.value ? 'primary' : 'default'));
</script>
<style scoped></style>

View File

@ -36,6 +36,7 @@ const style = computed(() => {
<style scoped>
.soybean-layout__main {
flex-grow: 1;
width: 100%;
transition-property: padding-left;
}
</style>

View File

@ -17,6 +17,7 @@
v-bind="commonProps"
:fixed="fixedHeaderAndTab"
:z-index="tabZIndex"
:min-width="minWidth"
:top="headerHeight"
:height="tabHeight"
:padding-left="siderWidth"
@ -46,6 +47,7 @@
v-bind="commonProps"
:fixed="fixedFooter"
:z-index="footerZIndex"
:min-width="minWidth"
:height="footerHeight"
:padding-left="siderWidth"
:style="footerTransform"

View File

@ -11,3 +11,10 @@ interface TraditionColor {
/** 中国传统颜色 */
export const traditionColors = colorJson as TraditionColor[];
export function isInTraditionColors(color: string) {
return traditionColors.some(item => {
const flag = item.data.some(v => v.color === color);
return flag;
});
}

View File

@ -3,28 +3,29 @@ import type { ThemeSetting } from '@/interface';
const themeColorList = [
'#1890ff',
'#007AFF',
'#2d8cf0',
'#409EFF',
'#536dfe',
'#2d8cf0',
'#007AFF',
'#5ac8fa',
'#5856D6',
'#536dfe',
'#9c27b0',
'#AF52DE',
'#0096c7',
'#00C1D4',
'#009688',
'#5AC8FA',
'#34C759',
'#71EFA3',
'#43a047',
'#7cb342',
'#c0ca33',
'#78DEC7',
'#FC5404',
'#ee4f12',
'#FF9500',
'#fadb14',
'#FFCC00',
'#FF3B30',
'#FF2D55',
'#ff5c93',
'#9c27b0',
'#AF52DE'
'#e53935',
'#d81b60',
'#f4511e',
'#fb8c00',
'#ffb300',
'#fdd835',
'#6d4c41',
'#546e7a'
];
const defaultThemeSetting: ThemeSetting = {
@ -47,6 +48,7 @@ const defaultThemeSetting: ThemeSetting = {
warning: '#faad14',
error: '#f5222d'
},
isCustomizeInfoColor: false,
fixedHeaderAndTab: true,
showReload: true,
header: {

View File

@ -1,6 +1,16 @@
import type { GlobalThemeOverrides } from 'naive-ui';
import { kebabCase } from 'lodash-es';
import { getColorPalette, addColorAlpha } from '@/utils';
import { cloneDeep, kebabCase } from 'lodash-es';
import { themeSetting } from '@/settings';
import { getThemeColor, getColorPalette, addColorAlpha } from '@/utils';
/** 获取主题配置 */
export function getThemeSettings() {
const themeColor = getThemeColor() || themeSetting.themeColor;
const info = themeSetting.isCustomizeInfoColor ? themeSetting.otherColor.info : getColorPalette(themeColor, 7);
const otherColor = { ...themeSetting.otherColor, info };
const setting = cloneDeep({ ...themeSetting, themeColor, otherColor });
return setting;
}
type ColorType = 'primary' | 'info' | 'success' | 'warning' | 'error';
type ColorScene = '' | 'Suppl' | 'Hover' | 'Pressed' | 'Active';
@ -38,7 +48,10 @@ function getThemeColors(colors: [ColorType, string][]) {
/** 获取naive的主题颜色 */
export function getNaiveThemeOverrides(colors: Record<ColorType, string>): GlobalThemeOverrides {
const { primary, info, success, warning, error } = colors;
const { primary, success, warning, error } = colors;
const info = themeSetting.isCustomizeInfoColor ? colors.info : getColorPalette(primary, 7);
const themeColors = getThemeColors([
['primary', primary],
['info', info],
@ -70,7 +83,7 @@ export function addThemeCssVarsToHtml(themeVars: ThemeVars) {
style.push(`--${kebabCase(key)}: ${themeVars[key]}`);
});
const styleStr = style.join(';');
document.documentElement.style.cssText = styleStr;
document.documentElement.style.cssText += styleStr;
}
/** windicss 暗黑模式 */

View File

@ -1,7 +1,5 @@
import { defineStore } from 'pinia';
import { darkTheme } from 'naive-ui';
import { cloneDeep } from 'lodash-es';
import { themeSetting } from '@/settings';
import type {
ThemeSetting,
ThemeLayoutMode,
@ -9,12 +7,12 @@ import type {
ThemeHorizontalMenuPosition,
ThemeAnimateMode
} from '@/interface';
import { getNaiveThemeOverrides, addThemeCssVarsToHtml } from './helpers';
import { getThemeSettings, getNaiveThemeOverrides, addThemeCssVarsToHtml } from './helpers';
type ThemeState = ThemeSetting;
export const useThemeStore = defineStore('theme-store', {
state: (): ThemeState => cloneDeep(themeSetting),
state: (): ThemeState => getThemeSettings(),
getters: {
/** naiveUI的主题配置 */
naiveThemeOverrides(state) {

View File

@ -1,7 +1,7 @@
import { watch, onUnmounted } from 'vue';
import { useOsTheme } from 'naive-ui';
import { useElementSize } from '@vueuse/core';
import { EnumStorageKey } from '@/enum';
import { setThemeColor } from '@/utils';
import { useThemeStore } from '../modules';
/** 订阅theme store */
@ -14,7 +14,7 @@ export default function subscribeThemeStore() {
const stopThemeColor = watch(
() => theme.themeColor,
newValue => {
window.localStorage.setItem(EnumStorageKey['theme-color'], `--primary-color: ${newValue};`);
setThemeColor(newValue);
},
{ immediate: true }
);

View File

@ -136,3 +136,11 @@ export function addColorAlpha(color: string, alpha: number) {
export function mixColor(firstColor: string, secondColor: string, ratio: number) {
return colord(firstColor).mix(secondColor, ratio).toHex();
}
/**
*
* @param color -
*/
export function isWhiteColor(color: string) {
return colord(color).isEqual('#ffffff');
}

View File

@ -5,3 +5,4 @@ export * from './number';
export * from './object';
export * from './icon';
export * from './design-pattern';
export * from './theme';

16
src/utils/common/theme.ts Normal file
View File

@ -0,0 +1,16 @@
import { EnumStorageKey } from '@/enum';
/**
*
* @param color
*/
export function setThemeColor(color: string) {
window.localStorage.setItem(EnumStorageKey['theme-color'], color);
}
/**
*
*/
export function getThemeColor() {
return window.localStorage.getItem(EnumStorageKey['theme-color']);
}