feat(projects): 添加缓存主题色
This commit is contained in:
parent
1d63a83822
commit
37092974d3
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,8 @@ export interface ThemeSetting {
|
||||
themeColorList: string[];
|
||||
/** 其他颜色 */
|
||||
otherColor: ThemeOtherColor;
|
||||
/** 是否自定义info的颜色(默认取比主题色深一级的颜色) */
|
||||
isCustomizeInfoColor: boolean;
|
||||
/** 固定头部和多页签 */
|
||||
fixedHeaderAndTab: boolean;
|
||||
/** 显示重载按钮 */
|
||||
|
@ -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"
|
||||
|
@ -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>
|
||||
|
@ -36,6 +36,7 @@ const style = computed(() => {
|
||||
<style scoped>
|
||||
.soybean-layout__main {
|
||||
flex-grow: 1;
|
||||
width: 100%;
|
||||
transition-property: padding-left;
|
||||
}
|
||||
</style>
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
});
|
||||
}
|
||||
|
@ -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: {
|
||||
|
@ -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 暗黑模式 */
|
||||
|
@ -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) {
|
||||
|
@ -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 }
|
||||
);
|
||||
|
@ -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');
|
||||
}
|
||||
|
@ -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
16
src/utils/common/theme.ts
Normal 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']);
|
||||
}
|
Loading…
Reference in New Issue
Block a user