Skip to content

Commit

Permalink
feat(projects): 添加缓存主题色
Browse files Browse the repository at this point in the history
  • Loading branch information
honghuangdc committed Jan 21, 2022
1 parent 1d63a83 commit 3709297
Show file tree
Hide file tree
Showing 15 changed files with 87 additions and 34 deletions.
4 changes: 1 addition & 3 deletions mock/api/route.ts
Expand Up @@ -12,8 +12,7 @@ const routes: AuthRoute.Route[] = [
component: 'self',
meta: {
title: '分析页',
requiresAuth: true,
keepAlive: true
requiresAuth: true
}
},
{
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions public/resource/loading.js
Expand Up @@ -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;
}

Expand Down
2 changes: 2 additions & 0 deletions src/interface/theme.ts
Expand Up @@ -13,6 +13,8 @@ export interface ThemeSetting {
themeColorList: string[];
/** 其他颜色 */
otherColor: ThemeOtherColor;
/** 是否自定义info的颜色(默认取比主题色深一级的颜色) */
isCustomizeInfoColor: boolean;
/** 固定头部和多页签 */
fixedHeaderAndTab: boolean;
/** 显示重载按钮 */
Expand Down
1 change: 1 addition & 0 deletions src/layouts/BasicLayout/index.vue
@@ -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"
Expand Down
Expand Up @@ -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';
Expand All @@ -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>
1 change: 1 addition & 0 deletions src/package/SoybeanLayout/src/components/LayoutContent.vue
Expand Up @@ -36,6 +36,7 @@ const style = computed(() => {
<style scoped>
.soybean-layout__main {
flex-grow: 1;
width: 100%;
transition-property: padding-left;
}
</style>
2 changes: 2 additions & 0 deletions src/package/SoybeanLayout/src/index.vue
Expand Up @@ -17,6 +17,7 @@
v-bind="commonProps"
:fixed="fixedHeaderAndTab"
:z-index="tabZIndex"
:min-width="minWidth"
:top="headerHeight"
:height="tabHeight"
:padding-left="siderWidth"
Expand Down Expand Up @@ -46,6 +47,7 @@
v-bind="commonProps"
:fixed="fixedFooter"
:z-index="footerZIndex"
:min-width="minWidth"
:height="footerHeight"
:padding-left="siderWidth"
:style="footerTransform"
Expand Down
7 changes: 7 additions & 0 deletions src/settings/color.ts
Expand Up @@ -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;
});
}
34 changes: 18 additions & 16 deletions src/settings/theme.ts
Expand Up @@ -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 = {
Expand All @@ -47,6 +48,7 @@ const defaultThemeSetting: ThemeSetting = {
warning: '#faad14',
error: '#f5222d'
},
isCustomizeInfoColor: false,
fixedHeaderAndTab: true,
showReload: true,
header: {
Expand Down
21 changes: 17 additions & 4 deletions src/store/modules/theme/helpers.ts
@@ -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';
Expand Down Expand Up @@ -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],
Expand Down Expand Up @@ -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 暗黑模式 */
Expand Down
6 changes: 2 additions & 4 deletions src/store/modules/theme/index.ts
@@ -1,20 +1,18 @@
import { defineStore } from 'pinia';
import { darkTheme } from 'naive-ui';
import { cloneDeep } from 'lodash-es';
import { themeSetting } from '@/settings';
import type {
ThemeSetting,
ThemeLayoutMode,
ThemeTabMode,
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) {
Expand Down
4 changes: 2 additions & 2 deletions src/store/subscribe/theme.ts
@@ -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 */
Expand All @@ -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 }
);
Expand Down
8 changes: 8 additions & 0 deletions src/utils/common/color.ts
Expand Up @@ -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');
}
1 change: 1 addition & 0 deletions src/utils/common/index.ts
Expand Up @@ -5,3 +5,4 @@ export * from './number';
export * from './object';
export * from './icon';
export * from './design-pattern';
export * from './theme';
16 changes: 16 additions & 0 deletions src/utils/common/theme.ts
@@ -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']);
}

0 comments on commit 3709297

Please sign in to comment.