实现原理
动态切换主题的功能是,通过ConfigProvider全局化配置,设置统一的样式前缀,具体ConfigProvider相关文档可以看这里:https://ant-design.gitee.io/components/config-provider-cn/#API。
举个例子,antd按钮控件,参数type设置为’primary’后,实际渲染出来后,会添加上class="ant-btn ant-btn-primary"的属性,其中ant-btn-primary样式控制按钮的背景色及边框线颜色。如下图:
对于类名ant-btn以及ant-btn-primary,ant实际上作为样式的前缀。而我们如果动态的将样式类名中的前缀统一替换成其他的字符串,就实现了主题切换的效果。
具体实现
注:在开始之前先配置框架支持less。具体配置请参阅另一篇文章:传送门
1、引入 antd.variable.min.css,替换当前项目引入样式文件为 CSS Variable 版本:
-- import 'antd/dist/antd.min.css';
++ import 'antd/dist/antd.variable.less';
2、依据官方文档,调用 ConfigProvider 配置方法设置主题色
import React, { useState } from 'react';
import ReactDOM from 'react-dom';
import reportWebVitals from './reportWebVitals';
import { Button, DatePicker, Radio, RadioChangeEvent, Space, version } from "antd";
import 'antd/dist/antd.css';
import { ConfigProvider } from 'antd';
import 'antd/dist/antd.variable.less';
const TestComponent = () => {
const [prefix, setPrefix] = useState("#1890ff");
ConfigProvider.config({
theme: {
primaryColor: prefix,
}
});
const handlePrefixChange = (e: RadioChangeEvent) => {
console.log(e,e.target.value)
setPrefix(e.target.value);
};
return (
<ConfigProvider>
<div className="App">
<h1>
<Space>
Change Theme:
{/* radio动态修改prefix */}
<Radio.Group onChange={handlePrefixChange} value={prefix}>
<Radio value="#1890ff">antd默认蓝色</Radio>
<Radio value="#25b864">自定义幽幽绿光</Radio>
</Radio.Group>
</Space>
</h1>
<h1>antd 当前版本: {version}</h1>
<DatePicker />
<Button type="primary" style={{ marginLeft: 8 }}>
Primary 按钮
</Button>
</div>
</ConfigProvider>
);
};
ReactDOM.render(<TestComponent />, document.getElementById("root"));
reportWebVitals();
最终效果