SoFunction
Updated on 2025-04-03

Dynamically switch topics using vue-antd

vue-antd dynamically switch topics

Installation dependencies

1 webpack-theme-color-replacer: yarn add webpack-theme-color-replacer@1.3.22
2 less: yarn add less@2.7.2
3 less-loader: yarn add less-loader@7.0.2

Add configuration in

const createThemeColorReplacerPlugin = require("./");
const vueConfig = {
  css: {
    loaderOptions: {
      less: {
        lessOptions: {
          modifyVars: { 
            //Note: The default value cannot be given here, otherwise it will cause the dynamic configuration of the theme color to fail.            // less vars,customize ant design theme
            //'primary-color': '#2f54eb',
            //'link-color': '#2f54eb',
            //'border-radius-base': '4px'
          },
          // DO NOT REMOVE THIS LINE
          javascriptEnabled: true,
        },
      },
    },
  },
  configureWebpack: {
    plugins: [createThemeColorReplacerPlugin()],
  },
  assetsDir: "static",
};
 = vueConfig;

Add theme color change method, create a new util folder

const ThemeColorReplacer = require('webpack-theme-color-replacer')
const generate = require('@ant-design/colors/lib/generate').default

const getAntdSerials = (color) => {
  // Fade (i.e. less tint)  const lightens = new Array(9).fill().map((t, i) => {
    return (color, i / 10)
  })
  const colorPalettes = generate(color)
  const rgb = .toNum3(('#', '')).join(',')
  return (colorPalettes).concat(rgb)
}

const themePluginOption = {
  fileName: 'css/theme-colors-[contenthash:8].css',
  matchColors: getAntdSerials('#1890ff'), // Main color series // Change the style selector to solve the style coverage problem  changeSelector (selector) {
    switch (selector) {
      case '.ant-calendar-today .ant-calendar-date':
        return ':not(.ant-calendar-selected-date):not(.ant-calendar-selected-day)' + selector
      case '.ant-btn:focus,.ant-btn:hover':
        return '.ant-btn:focus:not(.ant-btn-primary):not(.ant-btn-danger),.ant-btn:hover:not(.ant-btn-primary):not(.ant-btn-danger)'
      case '.,.ant-btn:active':
        return '.:not(.ant-btn-primary):not(.ant-btn-danger),.ant-btn:active:not(.ant-btn-primary):not(.ant-btn-danger)'
      case '.ant-steps-item-process .ant-steps-item-icon > .ant-steps-icon':
      case '.ant-steps-item-process .ant-steps-item-icon>.ant-steps-icon':
        return ':not(.ant-steps-item-process)' + selector
      case '.ant-menu-horizontal>.ant-menu-item-active,.ant-menu-horizontal>.ant-menu-item-open,.ant-menu-horizontal>.ant-menu-item-selected,.ant-menu-horizontal>.ant-menu-item:hover,.ant-menu-horizontal>.ant-menu-submenu-active,.ant-menu-horizontal>.ant-menu-submenu-open,.ant-menu-horizontal>.ant-menu-submenu-selected,.ant-menu-horizontal>.ant-menu-submenu:hover':
      case '.ant-menu-horizontal > .ant-menu-item-active,.ant-menu-horizontal > .ant-menu-item-open,.ant-menu-horizontal > .ant-menu-item-selected,.ant-menu-horizontal > .ant-menu-item:hover,.ant-menu-horizontal > .ant-menu-submenu-active,.ant-menu-horizontal > .ant-menu-submenu-open,.ant-menu-horizontal > .ant-menu-submenu-selected,.ant-menu-horizontal > .ant-menu-submenu:hover':
        return '.ant-menu-horizontal > .ant-menu-item-active,.ant-menu-horizontal > .ant-menu-item-open,.ant-menu-horizontal > .ant-menu-item-selected,.ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-item:hover,.ant-menu-horizontal > .ant-menu-submenu-active,.ant-menu-horizontal > .ant-menu-submenu-open,.ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-submenu-selected,.ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-submenu:hover'
      case '.ant-menu-horizontal > .ant-menu-item-selected > a':
      case '.ant-menu-horizontal>.ant-menu-item-selected>a':
        return '.ant-menu-horizontal:not(ant-menu-light):not(.ant-menu-dark) > .ant-menu-item-selected > a'
      case '.ant-menu-horizontal > .ant-menu-item > a:hover':
      case '.ant-menu-horizontal>.ant-menu-item>a:hover':
        return '.ant-menu-horizontal:not(ant-menu-light):not(.ant-menu-dark) > .ant-menu-item > a:hover'
      default :
        return selector
    }
  }
}

const createThemeColorReplacerPlugin = () => new ThemeColorReplacer(themePluginOption)

 = createThemeColorReplacerPlugin

Add a file

import client from "webpack-theme-color-replacer/client";
import generate from "@ant-design/colors/lib/generate";

function getAntdSerials(color) {
  // Fade (i.e. less tint)  const lightens = new Array(9).fill().map((t, i) => {
    return (color, i / 10);
  });
  // colorPalette transform to get color value  const colorPalettes = generate(color);
  const rgb = .toNum3(("#", "")).join(",");
  return (colorPalettes).concat(rgb);
}
function changeColor(newColor) {
  var options = {
    newColors: getAntdSerials(newColor), // new colors array, one-to-one corresponde with `matchColors`
    changeUrl(cssUrl) {
      return `/${cssUrl}`; // while router is not `hash` mode, it needs absolute path
    },
  };
  return (options, Promise);
}

export default {
  updateTheme(newPrimaryColor) {
    const hideMessage = () => ("Switching topics!", 0);
    changeColor(newPrimaryColor).finally((t) => {
      setTimeout(() => {
        hideMessage();
      });
    });
  },
};

Then introduce the method in the Vue prototype prototype

import utils from "./utils"
.$u = utils
//Note that the introduction of antd style must be changed from css to less- import 'ant-design-vue/dist/';
+ import 'ant-design-vue/dist/';

Then after the project is started, call the Vm.$ method to change the theme color dynamically.

Note that the method must pass the value in hexadecimal color. If the English character corresponding to the color is passed, it may cause an error.

If custom components or elements also need to manage theme colors uniformly, create a new one in the assets directory

@import "~ant-design-vue/dist/";
#home {
  color: @primary-color;
}

Introduce antd style, and then the theme color of antd is @primary-color, just use it directly

Then directly introduce

- import 'ant-design-vue/dist/';
+ import "./assets/css/"

Vue3.0 + Antd, modify the antd theme color, configure global css

1. Modify the configuration inside

 = {
  css: {
    loaderOptions: {
      less: {
        lessOptions: {
          modifyVars: {
            'primary-color': '#3d62ff',// Modify the global theme color          },
          javascriptEnabled: true,
        },
      },
    },
    extract: true, // Solve the problem of not extracting CSS during packaging.  }
}

2. Import ‘ant-design-vue/dist/’ in it;

Modify to import ‘ant-design-vue/dist/’;

When modifying css to less, an error will be reported.bezierEasingMixin()

The solution is: uninstall less-loader first

npm uninstall -D less-loader

Install less-loader@6.0.0 again

npm install -D less-loader@6.0.0

Then rerun the project

The above is personal experience. I hope you can give you a reference and I hope you can support me more.