React+antd在線上動態更換皮膚主題

開始

由於項目裏一個更換皮膚的功能,雖然antd官網給出了更改主題的方法,但那是靜態的,沒辦法在線上更換,而後發現網上在這方面的資料也並很少,這個業務難道不是應該很廣泛嗎?而後我就花了一些時間去解決了這個問題,並將踩過的坑寫出來,再給出解決方案。javascript

antd-theme-webpack-plugin

這個工具是我在網上找到的。下面是這個包的文檔,但這個文檔實際上寫的並不清楚,我在按文檔寫的過程裏遇到了不少的坑。css

antd-theme-webpack-plugin文檔html

咱們先在控制檯執行: yarn run antd-theme-webpack-plugin -Djava

而後去webpack.config.common.js裏配置:node

//頂部引入
const AntDesignThemePlugin = require('antd-theme-webpack-plugin');

//須要在less-loader裏配置options,這個配置是在less的配置規則下
{
    loader:'less-loader',
    options:{
    	//這裏須要在less的配置規則裏打開javascriptEnabled
        javascriptEnabled: true,
    }
}


//在plugins裏
plugins:[
	new AntDesignThemePlugin({
		antDir: path.join(__dirname, './node_modules/antd'),//antd包位置
    	stylesDir: path.join(__dirname, './src/styles/theme'),//指定皮膚文件夾
    	varFile: path.join(__dirname, './src/styles/theme/variables.less'),//本身設置默認的主題色
    	indexFileName: './public/index.html',
    	mainLessFile: path.join(__dirname, './src/styles/theme/index.less'),
    	outputFilePath: path.join(__dirname, './dist/theme/color.less'),//輸出到什麼地方
    	themeVariables: [//這裏寫要改變的主題變量
        	'@primary-color',
        	'@btn-primary-bg',
    	],
    	generateOnce:false
	})
]

複製代碼

這裏的配置有幾個坑點,等下結合後面一塊兒說。react

而後咱們去index.htmlwebpack

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>React</title>
</head>
<body>
    <link rel="stylesheet/less" type="text/css" href="./theme/color.less" /><!--這裏link放在哪,style生成在哪裏,注意樣式被覆蓋-->
    <script> window.less = { async: false, env: 'production'//production development }; </script>
    <div id="root"></div>
    <script src="https://cdn.bootcss.com/less.js/2.7.3/less.min.js"> </script>

</body>
</html>
複製代碼

html這裏有幾個坑: 1.注意link標籤放的位置,要放在body的第一行裏,由於到時候style是會生成在該ling標籤下面的,若是你把link放在head裏,到時候生成的主題樣式會被覆蓋掉。 2. 咱們須要在這裏引入less文件,由於咱們須要使用到window.less這個對象裏的方法,可是咱們不能引入less3.0以上的,否則瀏覽器控制檯會報下面這樣的錯,樣式也不會出現。 web

在這裏插入圖片描述

而後在styles的文件夾下建立文件,這裏文件建立的路徑須要和webpack.config.common.js裏寫的路徑同樣。npm

在這裏插入圖片描述
而後在variables.less裏:

//在頂部加上這一行
@import "~antd/lib/style/themes/default.less";

@primary-color: #6064f4;
@btn-primary-bg: #ccc849;
複製代碼

而後把要更換的主題顏色給寫上去,把antd默認的主題顏色給覆蓋掉,這裏有個坑的地方是,這裏的兩個顏色變量必定要寫上去,否則有的時候會出現更換主題顏色失敗的狀況。瀏覽器

index.less這個文件實際上是無關緊要的,咱們能夠不在裏面寫東西,可是我在項目裏用到了,後面會說。

而後咱們去頁面裏寫一下:

handleClick(){
        window.less.modifyVars(//更換主題顏色要這麼寫
            {
                '@primary-color': '#e64e14',
                '@btn-primary-bg': '#5d72cc',
            }
        )
        .then(() => {console.log('success')})
        .catch(error => {
            console.log(error);
        });
    }
    render() {
        return (
            <div className='minor-borderTop major-fontColor'> <Button onClick={this.handleClick} type={'primary'}>更換</Button> </div>
        )
    }
複製代碼

而後坑的地方來了,若是你想要使用variable.less裏的變量,通常來講咱們都是在本身新建的less文件的頂部引入這個文件,而後在用到顏色的地方直接加上@primary-color這個變量,可是這裏不行,由於它只會把variables.less和index.less這兩個文件裏的變量給更改了,其餘的文件是固定生成的,不會被覆蓋。因此若是你想用得反過來,好比在新建的less文件裏使用變量,而後在variables.less的頂部引入。但這樣確定是很差的,react有那麼多組件,若是每一個都引入到這個variabkes.less的頂部的話,那得多大?

而後我想了兩個辦法,

  1. 使用css的變量var,在variabkes.less文件裏,像下面這樣寫:
@primary-color: #6064f4;
@btn-primary-bg: #ccc849;

:root{
  --primary:@primary-color;
}
複製代碼

這樣子你須要使用的less文件裏就能夠引入variabkes.less文件,而後這樣寫background:var(--primary),這樣在@primary-color改變了以後,--primary也能夠拿到了。可是這個方法有兼容性問題,ie徹底不支持css變量,因此這個方法適合不須要兼容ie的使用。

  1. 這裏就用到了我以前說的index.less,咱們在index.less的頂部引入variabkes.less,在裏面寫:
.primary-bg{
  background-color:@primary-color;
}

.fontColor{
  color:@primary-8;
}
複製代碼

咱們能夠直接新建幾個類,寫上背景顏色,文字顏色,等@primary-color改變的時候,類裏的顏色也會發生改變。而後在須要的地方引用這個index.less,而後去組件里加上這個類就好了。其實這個方法算是稍微有點low,可是這個也算是一個比較好的解決辦法,由於你要加的類其實沒有幾個,背景顏色類,字體顏色類。這裏講一下你要改變的顏色變量必需要是antd定義好的,你本身定義一個好比@primary-fontColor是沒用的,由於antd並無這個變量,若是你要看antd定義了哪些變量,能夠去node_modules/antd/lib/style/themes/default.less這個文件裏看。上面那裏我使用的@primary-8這個變量就是antd本身定義的,這個變量是根據@primary-color的顏色來變化的,因此咱們不須要在webpack引入,數字越大顏色越深。

而後開始打包,你須要在dist文件夾下建立一個theme文件夾,而後才能去執行打包命令,而後你會發現,在theme文件夾下有一個color.less文件,在根目錄下也有一個color.less文件,你能夠把根目錄下的color.less刪除,這個是多餘生成的。

而後咱們打開本身寫的頁面:

在這裏插入圖片描述
能夠發現主題顏色是咱們在variables.less定義的默認顏色,而後咱們點擊按鈕,頁面變成了下面這樣:
在這裏插入圖片描述
變成了咱們在按鈕點擊事件裏定義的顏色了。
在這裏插入圖片描述
咱們發現link下面生成了一個style文件,這裏就是以前說的顏色注意被覆蓋的問題了。

若是你想要更多的顏色,能夠引入調色盤的組件去改變主題顏色,好比antd官網拉到最下方能夠改變主題顏色那樣。

結尾

這章寫了不少東西,主要是有坑的地方太多了,我寫的又比較詳細,但同時感受也寫的有點複雜了,若是又不懂的能夠在評論裏問。

相關文章
相關標籤/搜索