天热了,给网站换套清凉的肤色吧__Vue.js
发布于 2 个月前 作者 banyungong 201 次浏览 来自 分享
粉丝福利 : 关注VUE中文社区公众号,回复视频领取粉丝福利

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

效果演示

源码地址:码云

原理简述

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

实现方案

定义一份覆盖组件的样式

theme.less

@primary-color: #1890ff;

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

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

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

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

  2. 引用less库必须要在less配置之后。

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

     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.js

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

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 %>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虽然很简单,但是实际项目中的换肤原理也是如此。

版权声明:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 作者: 取名字真难啊 原文链接:https://juejin.im/post/6970603494646497311

回到顶部