天熱了,給網站換套清涼的膚色吧

參考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雖然很簡單,可是實際項目中的換膚原理也是如此。

相關文章
相關標籤/搜索