Last week, I studied the design of Vben Admin’s environment variables and permissions. Now the project is in use and still in the stage of building the page structure. In the theme, it needs to be modified, so I have a look at the implementation of this part.
- Vben Admin in-depth understanding of plug-in, environment variable design
- Vben Admin in-depth understanding of routing, menu, permission design
Doubt point
This part mainly analyzes the configuration related to the topic and how to define and modify the topic.
- How is the theme switched and what is the logic?
- How do YOU define which configurations need to change for a topic?
Subject definition
Click on Settings, you can set theme, system theme, top bar theme, menu theme to see where the configuration order is.
Configuration of the list of available colors.
// src/settings/designSetting.ts
// app theme preset color
export const APP_PRESET_COLOR_LIST: string[] = [
/ *... * /
];
// header preset color
export const HEADER_PRESET_BG_COLOR_LIST: string[] = [
/ *... * /
];
// sider preset color
export const SIDE_BAR_BG_COLOR_LIST: string[] = [
/ *... * /
];
Copy the code
The item configuration associated with the topic updates these values as the topic changes.
// src/settings/projectSetting.ts
const setting = {
// Project theme color
themeColor: primaryColor,
// Site grey mode
grayMode: false.// Color fade mode
colorWeak: false.// Header configuration
headerSetting: {
/ / the background color
bgColor: '#ffffff'./ / theme
theme: MenuThemeEnum.LIGHT,
}
// Menu configuration
menuSetting: {
/ / the background color
bgColor: '# 273352'.// Menu theme
theme: MenuThemeEnum.DARK
}
}
Copy the code
Theme plug-in Configuration
Take a look at the viet-plugin-theme plug-in before analyzing the implementation, since it is based on this implementation.
This plug-in does two main things: load the ant-Design-Vue dark theme configuration and replace one color value with another.
Customize the theme based on ant-Design-Vue’s official documentation – Implement the Dark theme with getThemeVariables provided in the Dark Theme and do some additional customization.
// build/generate/generateModifyVars.ts
import { getThemeVariables } from 'ant-design-vue/dist/theme';
export function generateModifyVars(dark = false) {
const modifyVars = getThemeVariables({ dark });
return {
...modifyVars
};
}
// build/vite/plugin/theme
import { antdDarkThemePlugin } from 'vite-plugin-theme';
export function configThemePlugin() {
const plugin = [
antdDarkThemePlugin({
darkModifyVars: {
...generateModifyVars(true)}}); ]return plugin
}
Copy the code
Another configuration is to replace one color value with another color value, which is more complicated to deal with in the source code using a simplified example. Suppose you have a style definition.
.test {
color: #e72528;
}
Copy the code
Define the plug-in and set it to match the colors you want to change.
// build/vite/plugin/theme
import { viteThemePlugin } from 'vite-plugin-theme';
export function configThemePlugin() {
const plugin = [
viteThemePlugin({
// Match the color you want to change
colorVariables: ["#e72528"]}); ]return plugin
}
Copy the code
Then implement a function to replace the color value of the stylesheet.
import { replaceStyleVariables } from "vite-plugin-theme/es/client";
export async function changeThemeColor(color: string) {
return await replaceStyleVariables({
colorVariables: [color]
});
}
Copy the code
When changeThemeColor(“#1d1b1b”) is called, the result is as follows.
.test {
color: #e72528;
}
/* One more style overrides the previous */
.test {
color: #e72528;
}
Copy the code
Topic switching processing
When the theme switch is found to be processed by a function, so focus on how this function is processed.
// src/layouts/default/setting/SettingDrawer.tsx
function renderHeaderTheme() {
// ...
baseHandler(event, value);
}
function renderSiderTheme() {
// ...
baseHandler(event, value);
}
function renderMainTheme() {
// ...
baseHandler(event, value);
}
Copy the code
Call different functions on each branch for separate processing, and let’s look at the implementation of each function.
// src/layouts/default/setting/handler.ts
export function baseHandler(event: HandlerEnum, value: any) {
const appStore = useAppStore();
// Handle the setting type
const config = handler(event, value);
// Update the project configuration
appStore.setProjectConfig(config);
}
export function handler(event: HandlerEnum, value: any) :DeepPartial<ProjectConfig> {
const appStore = useAppStore();
const { getThemeColor, getDarkMode } = useRootSetting();
switch (event) {
// Update the system color
case HandlerEnum.CHANGE_THEME_COLOR:
if (getThemeColor.value === value) {
return {};
}
changeTheme(value);
return { themeColor: value };
// Update the system theme
case HandlerEnum.CHANGE_THEME:
if (getDarkMode.value === value) {
return {};
}
updateDarkTheme(value);
return {};
// Update the menu theme
case HandlerEnum.MENU_THEME:
updateSidebarBgColor(value);
return { menuSetting: { bgColor: value } };
// Update the top column theme
case HandlerEnum.HEADER_THEME:
updateHeaderBgColor(value);
return { headerSetting: { bgColor: value } }; }}Copy the code
The system theme
Calling changeTheme to update the system theme is done using the color value substitution stylesheet method above, as configured above.
// src/logics/theme/index.ts
export async function changeTheme(color: string) {
const colors = generateColors({
mixDarken,
mixLighten,
tinycolor,
color
});
return await replaceStyleVariables({
colorVariables: [...getThemeColors(color), ...colors]
});
}
Copy the code
Default theme and dark theme
Call updateDarkTheme to update the dark theme and switch the dark theme by changing the DATA-theme attribute of the HTML tag.
// src/logics/theme/dark.ts
export async function updateDarkTheme(mode: string | null = "light") {
const htmlRoot = document.getElementById("htmlRoot");
if (mode === "dark") {
if (import.meta.env.PROD && ! darkCssIsReady) {await loadDarkThemeCss();
}
htmlRoot.setAttribute("data-theme"."dark");
} else {
htmlRoot.setAttribute("data-theme"."light"); }}Copy the code
Use sample columns.
[data-theme="dark"] {
/* Dark theme theme style */
}
[data-theme="light"] {
/* Color theme theme style */
}
Copy the code
Top bar theme and menu theme
The top bar and menu styles are implemented using the CSS function var to get the style variables and update the variable values on the HTML properties.
// src/logics/theme/updateBackground.ts
export function updateHeaderBgColor(color) {
setCssVar("--header-bg-color", color);
// ...
}
export function updateSidebarBgColor(color) {
setCssVar("--sider-dark-bg-color", color);
// ...
}
Copy the code
Use sample columns.
html{-header-bg-color: # 394664;
--sider-dark-bg-color: # 273352;
}
.ant-layout-sider-dark {
background-color: var(--sider-dark-bg-color);
}
.vben-layout-header--dark {
background-color: var(--header-bg-color);
}
Copy the code
Color weak mode and gray mode
There are also two theme modes that change the project color as a whole, using filters.
// src/logics/theme/updateColorWeak.ts
export function updateColorWeak(colorWeak: boolean) {
toggleClass(colorWeak, "color-weak".document.documentElement);
}
// src/logics/theme/updateGrayMode.ts
export function updateGrayMode(gray: boolean) {
toggleClass(gray, "gray-mode".document.documentElement);
}
Copy the code
.color-weak {
filter: invert(80%);
}
.gray-mode {
filter: grayscale(100%);
filter: progid:dximagetransform.microsoft.basicimage(grayscale=1);
}
Copy the code
conclusion
No summary, the existing Vben Admin common situation has been handled when writing new components should try to use defined variables, take advantage of the existing theme rules.