初始化项目
This commit is contained in:
158
src/store/modules/theme/index.ts
Normal file
158
src/store/modules/theme/index.ts
Normal file
@@ -0,0 +1,158 @@
|
||||
import { computed, effectScope, onScopeDispose, ref, toRefs, watch } from 'vue';
|
||||
import type { Ref } from 'vue';
|
||||
import { defineStore } from 'pinia';
|
||||
import { useEventListener, usePreferredColorScheme } from '@vueuse/core';
|
||||
import { SetupStoreId } from '@/enum';
|
||||
import { localStg } from '@/utils/storage';
|
||||
import { addThemeVarsToHtml, createThemeToken, getAntdTheme, initThemeSettings, toggleCssDarkMode } from './shared';
|
||||
|
||||
/** Theme store */
|
||||
export const useThemeStore = defineStore(SetupStoreId.Theme, () => {
|
||||
const scope = effectScope();
|
||||
const osTheme = usePreferredColorScheme();
|
||||
|
||||
/** Theme settings */
|
||||
const settings: Ref<App.Theme.ThemeSetting> = ref(initThemeSettings());
|
||||
|
||||
/** Reset store */
|
||||
function resetStore() {
|
||||
const themeStore = useThemeStore();
|
||||
|
||||
themeStore.$reset();
|
||||
}
|
||||
|
||||
/** Theme colors */
|
||||
const themeColors = computed(() => {
|
||||
const { themeColor, otherColor, isInfoFollowPrimary } = settings.value;
|
||||
const colors: App.Theme.ThemeColor = {
|
||||
primary: themeColor,
|
||||
...otherColor,
|
||||
info: isInfoFollowPrimary ? themeColor : otherColor.info
|
||||
};
|
||||
return colors;
|
||||
});
|
||||
|
||||
/** Dark mode */
|
||||
const darkMode = computed(() => {
|
||||
if (settings.value.themeScheme === 'auto') {
|
||||
return osTheme.value === 'dark';
|
||||
}
|
||||
return settings.value.themeScheme === 'dark';
|
||||
});
|
||||
|
||||
/** Antd theme */
|
||||
const antdTheme = computed(() => getAntdTheme(themeColors.value, darkMode.value));
|
||||
|
||||
/**
|
||||
* Settings json
|
||||
*
|
||||
* It is for copy settings
|
||||
*/
|
||||
const settingsJson = computed(() => JSON.stringify(settings.value));
|
||||
|
||||
/**
|
||||
* Set theme scheme
|
||||
*
|
||||
* @param themeScheme
|
||||
*/
|
||||
function setThemeScheme(themeScheme: UnionKey.ThemeScheme) {
|
||||
settings.value.themeScheme = themeScheme;
|
||||
}
|
||||
|
||||
/** Toggle theme scheme */
|
||||
function toggleThemeScheme() {
|
||||
const themeSchemes: UnionKey.ThemeScheme[] = ['light', 'dark', 'auto'];
|
||||
|
||||
const index = themeSchemes.findIndex(item => item === settings.value.themeScheme);
|
||||
|
||||
const nextIndex = index === themeSchemes.length - 1 ? 0 : index + 1;
|
||||
|
||||
const nextThemeScheme = themeSchemes[nextIndex];
|
||||
|
||||
setThemeScheme(nextThemeScheme);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set theme layout
|
||||
*
|
||||
* @param mode Theme layout mode
|
||||
*/
|
||||
function setThemeLayout(mode: UnionKey.ThemeLayoutMode) {
|
||||
settings.value.layout.mode = mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update theme colors
|
||||
*
|
||||
* @param key Theme color key
|
||||
* @param color Theme color
|
||||
*/
|
||||
function updateThemeColors(key: App.Theme.ThemeColorKey, color: string) {
|
||||
if (key === 'primary') {
|
||||
settings.value.themeColor = color;
|
||||
} else {
|
||||
settings.value.otherColor[key] = color;
|
||||
}
|
||||
}
|
||||
|
||||
/** Setup theme vars to html */
|
||||
function setupThemeVarsToHtml() {
|
||||
const { themeTokens, darkThemeTokens } = createThemeToken(themeColors.value);
|
||||
addThemeVarsToHtml(themeTokens, darkThemeTokens);
|
||||
}
|
||||
|
||||
/** Cache theme settings */
|
||||
function cacheThemeSettings() {
|
||||
const isProd = import.meta.env.PROD;
|
||||
|
||||
if (!isProd) return;
|
||||
|
||||
localStg.set('themeSettings', settings.value);
|
||||
}
|
||||
|
||||
// cache theme settings when page is closed or refreshed
|
||||
useEventListener(window, 'beforeunload', () => {
|
||||
cacheThemeSettings();
|
||||
});
|
||||
|
||||
// watch store
|
||||
scope.run(() => {
|
||||
// watch dark mode
|
||||
watch(
|
||||
darkMode,
|
||||
val => {
|
||||
toggleCssDarkMode(val);
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
// themeColors change, update css vars and storage theme color
|
||||
watch(
|
||||
themeColors,
|
||||
val => {
|
||||
setupThemeVarsToHtml();
|
||||
|
||||
localStg.set('themeColor', val.primary);
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
});
|
||||
|
||||
/** On scope dispose */
|
||||
onScopeDispose(() => {
|
||||
scope.stop();
|
||||
});
|
||||
|
||||
return {
|
||||
...toRefs(settings.value),
|
||||
resetStore,
|
||||
settingsJson,
|
||||
darkMode,
|
||||
themeColors,
|
||||
antdTheme,
|
||||
toggleThemeScheme,
|
||||
setThemeScheme,
|
||||
updateThemeColors,
|
||||
setThemeLayout
|
||||
};
|
||||
});
|
||||
Reference in New Issue
Block a user