After adding a dark theme to my nextjs development blog last time (the source code of nextJS blog that some people want has been uploaded to Github, blog-Template-Nextjs), I have been learning to use vue3 and Vite development environment for the past few months, and wanted to bring the dark theme to my demo project. It was conceived and realized.

Description: Bright white and dark theme switching practice for ANTD in NextJS. Online preview: The portal switches themes in a drop-down menu on the page, and is currently available in black and white, all white and Diablo. Code repository: vue3-admin

preview

The login

  1. Dark theme

  1. White theme

The workbench

  1. Dark theme

  1. White pattern

implementation

Principle: Using the antd-theme-Generator library, pull the styles from ant-design-vue and the styles used in the project (written by less) into color.less. The getLessVars method is used to package the multiple subject variable configurations into JSON files one by one and reference them in the project. Finally, the global styles are changed in the production environment by calling the less.modifyVars method (less will delete the current style tags and generate new style tags based on the variable values provided).

The core code

Since the antd-theme-webpack-plugin provided by the author of antd-theme-generator is not available in the vite environment, here is a simple replacement for the vite plugin: vite-plugin-antd-theme. It encapsulates the json generation behavior and automatically calls the generateTheme method.

Install vite – plugin – antd – theme

yarn add vite-plugin-antd-theme -D
Copy the code

The vite-plugin-antd-theme is actively dependent on the ANTd-theme-generator, so the main project does not need to be installed again and does not need to import methods from it. And vite-plugin-antd-theme exports the input parameter types required by antd-theme-generator.


vite.config.ts

import path from 'path';
import { UserConfigExport, ConfigEnv } from 'vite';
import viteAntdTheme, { ThemeEntry, AntdThemeOptions } from 'vite-plugin-antd-theme';

const themesEntry: Array<ThemeEntry> = [
  // Dark themes
  {
    entryPath: './node_modules/ant-design-vue/lib/style/themes/dark.less'.outputName: 'dark'.outputPath: './src/config'
  },
  // Default theme
  {
    entryPath: './src/styles/vars.less'.outputName: 'light'.outputPath: './src/config'
  },
  // Compact theme
  {
    entryPath: './node_modules/ant-design-vue/lib/style/themes/compact.less'.outputName: 'compact'.outputPath: './src/config'}];const options: AntdThemeOptions = {
  themesEntry,
  // Whether to extract all variables. The default is false and the priority is lower than setting themeVariables
  allVariables: true.// The following are the antd-theme-generator configuration items
  antDir: path.join(__dirname, './node_modules/ant-design-vue'),
  stylesDir: path.join(__dirname, './src'), // all files with .less extension will be processed
  varFile: path.join(__dirname, './src/styles/vars.less'), // default path is Ant Design default.less file
  themeVariables: [].outputFilePath: path.join(__dirname, './public/static/color.less'), // if provided, file will be created with generated less/styles
  customColorRegexArray: [/^fade\(.*\)$/] // An array of regex codes to match your custom color variable values so that code can identify that it's a valid color.  Make sure your regex does not adds false positives.
};

export default ({ command }: ConfigEnv): UserConfigExport= > {
  return {
    plugins: [
      viteAntdTheme(options)
    ]
  };
};
Copy the code

As you can see, the default configuration items are still numerous, and the plan is to encapsulate them later in the 1.0.2 release.


styles/vars.less

// This file will contain all varibales, our custom varibales and
//those from Ant Design which we want to override.
@import '.. /.. /node_modules/ant-design-vue/lib/style/themes/default.less';
@primary-color: @green-6;
@select-item-selected-option-color: @primary-color;
@processing-color: @primary-color;
@select-item-selected-bg: @background-color-base;
@secondary-color: @primary-color;
@skeleton-color: @primary-color;
@btn-primary-bg: @primary-color;

:root {
  --PC: @primary-color;
}
Copy the code

Here you can customize the theme color. The meaning of the variable name mainly refers to ant-design-vue.


index.html

<body>
  <div id="app"></div>
  <script type="module" src="/src/main.ts"></script>
  <link rel="stylesheet/less" type="text/css" href="/static/color.less" />
  <script src="/static/libs/less.min.js"></script>
</body>
Copy the code

A version 2.7.3 of browser-side less is required for online theme styling. Color.less will be generated automatically when the project is running. < span style = “color: less” style = “color: less” style = “color: less” style = “line-height: 13px;


main.ts

Here the global introduction of ANTD less style.

import 'ant-design-vue/dist/antd.less';
Copy the code

store/modules/setting.ts

import Final from '@/config/keys';
import darkVars from '@/config/dark.json';
import lightVars from '@/config/light.json';

export type Themes = 'dark' | 'light' | 'mix';

export interface SettingStateType {
  / / theme
  theme: Themes;
}

// Manually call global modifyVars
const lessHandler = (themeName: Themes) = > {
  switch (themeName) {
    case 'dark': {(window as any).less.modifyVars(darkVars);
      break;
    }
    case 'light': {(window as any).less.modifyVars(lightVars);
      break;
    }
    case 'mix': {(window asany).less.modifyVars(lightVars); }}};// Read the cached topic
const cacheTheme = localStorage.getItem(Final.THEME);

const state: SettingStateType = {
  theme:
    (cacheTheme === 'dark' && 'dark') ||
    (cacheTheme === 'light' && 'light') ||
    (cacheTheme === 'mix' && 'mix') | |'dark'
};

// The theme is automatically changed for the first time
lessHandler(state.theme);

const mutations = {
  // Change the theme
  themeChanged(state: SettingStateType, payload: { theme: Themes }): void {
    state.theme = payload.theme;
    localStorage.setItem(Final.THEME, payload.theme); lessHandler(payload.theme); }};const actions = {};

export default {
  namespaced: true,
  state,
  mutations,
  actions
};
Copy the code

The implementation of VUe3-admin is to commit mutation to automatically trigger the topic change logic.

At this point, the function is roughly realized, only need to add the trigger.

At the end of the article

Vue3-admin is a background management project using the Vue3 series, vite development environment and pure TSX syntax. Although vue is mainly promoting template syntax, but also hope that this way can let you learn something. The author mainly thinks that it can narrow the distance between React and VUE, and in the process of TSX writing, VScode can provide more friendly hints. Note items, transformation items, and some craters written by THE TSX are partially commented in the project.