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官网拉到最下方能够改变主题颜色那样。

结尾

这章写了不少东西,主要是有坑的地方太多了,我写的又比较详细,但同时感受也写的有点复杂了,若是又不懂的能够在评论里问。

相关文章
相关标签/搜索