天热了,给网站换套清凉的肤色吧

参考jeecg-boot的代码,实现一个简单的网站换肤demo。javascript

效果演示

源码地址:码云css

原理简述

使用less变量编写一套覆盖原组件的样式,在主题切换时调用window.less .modifyVars(color)函数,会从新生成一套新的样式。html

实现方案

定义一份覆盖组件的样式

theme.lessvue

@primary-color: #1890ff;

.ant-btn-primary {
  background-color: @primary-color;
  border-color: @primary-color;
}
复制代码

加载覆盖组件的less样式和less库

文件引入顺序须要特别注意:java

  1. 引用less覆盖样式必需要**放在index.html中的head标签以后。**由于项目中使用的ant-design-vue会把样式加载到head标签里最后,因此样式必需要在ant-design-vue以后才能生效。node

  2. 引用less库必需要在less配置以后。git

  3. 引用less库必需要在less覆盖样式以后。由于less库在初始化时,会经过less文件生成一份style文件,style文件的插入位置是在less样式节点的下一个节点以前,简而言之位置是在less文件以后。插入文件以后的修改只会修改style文件。具体参考less源码中的createCSS函数。markdown

    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.");
                        }
                    },
    复制代码

less.config.jsapp

window.less = {
    async: true,
    env: "production",
    javascriptEnabled: true,
};
复制代码

index.htmlless

<!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 %>favicon.ico">
    <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>
复制代码

在vue文件中,调用函数进行主题变量的修改

const updateTheme = primaryColor => {
    if (!primaryColor) {
        return;
    }
    const hideMessage = message.loading("正在编译主题!", 0);
    window.less
        .modifyVars({
            "@primary-color": primaryColor,
        })
        .finally(() => {
            hideMessage();
        });
};
复制代码

demo虽然很简单,可是实际项目中的换肤原理也是如此。

相关文章
相关标签/搜索