Refer to the code of JeECG-boot to achieve a simple website skin demo.

Results demonstrate

Source address: code cloud

The principle is briefly

Writing a style that overrides the original component using the less variable, and calling the window.less.modifyVars (color) function when the theme is switched generates a new style.

Implementation scheme

Define a style that covers the component

theme.less

@primary-color: #1890ff;

.ant-btn-primary {
  background-color: @primary-color;
  border-color: @primary-color;
}
Copy the code

Load the less style and less library that overrides the component

The order in which files are introduced requires special attention:

  1. References to less override styles must be placed ** after the head tag in index.html. ** Because the ant-design-vue used in the project loads the styles into the head tag, the styles must be applied after ant-design-vue.

  2. Reference to the less library must follow the LESS configuration.

  3. References to less libraries must come after the less override style. Because the less library generates a style file from the less file when initialized, the style file is inserted before the next node of the less style node, in short, after the less file. Changes made after inserting the file will only modify the style file. Refer to the createCSS function in the less source code.

    createCSS: function (a, b, c) { var e = c.href || "", f = "less:" + (c.title || d.extractId(e)), g = a.getElementById(f), h = ! 1, i = a.createElement("style"); i.setAttribute("type", "text/css"), c.media && i.setAttribute("media", c.media), i.id = f, i.styleSheet || (i.appendChild(a.createTextNode(b)), h = null ! == g && g.childNodes.length > 0 && i.childNodes.length > 0 && g.firstChild.nodeValue === i.firstChild.nodeValue); var j = a.getElementsByTagName("head")[0]; if (null === g || h === ! 1) { var k = c && c.nextSibling || null; k ? k.parentNode.insertBefore(i, k) : j.appendChild(i); } if (g && h === ! 1 && g.parentNode.removeChild(g), i.styleSheet) try { i.styleSheet.cssText = b; } catch (l) { throw new Error("Couldn't reassign styleSheet.cssText."); }},Copy the code

less.config.js

window.less = {
    async: true,
    env: "production",
    javascriptEnabled: true,
};
Copy the code

index.html

<! DOCTYPE html> <html lang=""> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta Name ="viewport" content="width=device-width,initial-scale=1.0"> <link rel="icon" href="<%= BASE_URL %> <title><%= htmlWebpackPlugin.options.title %></title> </head> <body> <noscript> <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> </noscript> <div id="app"></div> <! -- built files will be auto injected --> <link rel="stylesheet/less" href="<%= BASE_URL %>css/theme.less"> <script src="<%= BASE_URL %>js/less.config.js"></script> <script src="<%= BASE_URL %>js/less.min.js"></script> </body> </html>Copy the code

In the VUE file, the function is called to modify the topic variable

const updateTheme = primaryColor => { if (! primaryColor) { return; } const hideMessage = message.loading(" Compiling topic!" , 0); window.less .modifyVars({ "@primary-color": primaryColor, }) .finally(() => { hideMessage(); }); };Copy the code

The demo is pretty simple, but the same is true of skin peels in real projects.