在没风的地方找太阳  在你冷的地方做暖阳 人事纷纷  你总太天真  往后的余生  我只要你 往后余生  风雪是你  平淡是你  清贫也是你 荣华是你  心底温柔是你  目光所致  也是你 想带你去看晴空万里  想大声告诉你我为你着迷 往事匆匆  你总会被感动  往后的余生  我只要你 往后余生  冬雪是你  春花是你  夏雨也是你 秋黄是你  四季冷暖是你  目光所致  也是你 往后余生  风雪是你  平淡是你  清贫也是你 荣华是你  心底温柔是你  目光所致  也是你
jQuery火箭图标返回顶部代码 - 站长素材

React + Antd实现动态切换主题功能

本文摘自【前端早茶】

React + Antd 实现动态切换主题功能

前言

最近去ant design官网查阅资料,发现ant design最新版本已经更新到了4.17.x,于是比较粗略的看了一下最近几个4.17.x版本的更新日志,发现4.17.0版本更新了大量内容(点击查看4.17.0版本更新日志),在这其中比较吸引我注意点一点是实现了动态主题的功能。不过点看动态主题的文档,却标明着是实验性的功能,真是一个大写的囧。。。
4.17.0之前的版本里,实现动态主题的方法比较麻烦(也可能是我孤陋寡闻),通常是通过修改less变量的方式实现的,我个人觉得还是比较繁琐的。在4.17.0版本后官方开始支持动态切换主题的功能,这点让我感到比较欣慰。

注意事项

以下摘自官方文档的描述:

  • 该功能通过动态修改 CSS Variable 实现,因而在 IE 中页面将无法正常展示。请先确认你的用户环境是否需要支持 IE。
  • 该功能在 antd@4.17.0-alpha.0 版本起支持。

实现原理

动态切换主题的功能是,通过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-primary样式

对于类名ant-btn以及ant-btn-primaryant实际上作为样式的前缀。而我们如果动态的将样式类名中的前缀统一替换成其他的字符串,就实现了主题切换的效果。

 

具体实现

  1. 依据官方文档,通过ConfigProfider在顶层修改prefixCls

    复制代码
    import { ConfigProvider } from 'antd';
    
    export default () => (
      <ConfigProvider prefixCls="custom">
        <MyApp />
      </ConfigProvider>
    );
    复制代码

     

  2. 编译less
    由于步骤1中,通过ConfigProfider将样式类名前缀调整为custom,我们需要重新通过lessc命令,将antd的默认样式less文件,重新编译生成一份css文件。※注意:如果未安装less,则需要安装less:npm install -g less

    lessc --modify-var="ant-prefix=custom" node_modules/antd/dist/antd.variable.less custom.css
    

    如果单单按照官方文档中的操作执行上述命令,控制台会报错:

    SyntaxError: Inline JavaScript is not enabled. Is it set in your options? in D:\workspace\workspace_for_java\SPB-LERN\web-react-ts\node_modules\antd\lib\style\color\bezierEasing.less on line 110, column 1:
    109 // https://github.com/ant-design/ant-motion/issues/44
    110 .bezierEasingMixin();
    111 
    

    因为默认lessc命令未开启javascript功能,需要通过参数开启javascript功能,参考链接:https://lesscss.org/usage/#less-options-enable-inline-javascript-deprecated-。将上述命令添加--js参数后执行即可:

    lessc --js --modify-var="ant-prefix=custom" node_modules/antd/dist/antd.variable.less custom.css    
    
  3. 按照步骤2中的命令,会生成一个custom.css,由于文件过于庞大,截取几段内容如下:

    html {
      --custom-primary-color: #1890ff;
      --custom-primary-color-hover: #40a9ff;
      --custom-primary-color-active: #096dd9;
      --custom-primary-color-outline: rgba(24, 144, 255, 0.2);
      --custom-primary-1: #e6f7ff;
      --custom-primary-2: #bae7ff;
      --custom-primary-3: #91d5ff;
      --custom-primary-4: #69c0ff;
      --custom-primary-5: #40a9ff;
      --custom-primary-6: #1890ff;
      --custom-primary-7: #096dd9;
      --custom-primary-color-deprecated-pure: ;
      --custom-primary-color-deprecated-l-35: #cbe6ff;
      --custom-primary-color-deprecated-l-20: #7ec1ff;
      --custom-primary-color-deprecated-t-20: #46a6ff;
      --custom-primary-color-deprecated-t-50: #8cc8ff;
      --custom-primary-color-deprecated-f-12: rgba(24, 144, 255, 0.12);
      --custom-primary-color-active-deprecated-f-30: rgba(230, 247, 255, 0.3);
      --custom-primary-color-active-deprecated-d-02: #dcf4ff;
      /* 以下内容略去 */
    

    其中第二行中的--custom-primary-color即为primary的样色,默认为antd默认的蓝色,用于测试效果,我们可以将该改色修改为红色:

      html {
        --custom-primary-color: #ff0000;/* 修改为红色 */
        --custom-primary-color-hover: #40a9ff;
    
  4. index.js文件引入上述步骤中的custom.css文件。※注意:默认的antd样式文件antd/dist/antd.css也需要引入。index.js文件完整代码如下:

    import React, { useState } from "react";
    import ReactDOM from "react-dom";
    import { Button, DatePicker, Radio, Space, version } from "antd";
    import { ConfigProvider } from "antd";
    
    import "antd/dist/antd.css";  // antd默认样式文件
    import "./custom.css";  // 修改后的样式文件
    import "./index.css";
    
    const TestComponent = () => {
      const [prefix, setPrefix] = useState("ant");
    
      const handlePrefixChange = (e) => {
        setPrefix(e.target.value);
      };
    
      return (
        // ConfigProvider修改prefixCls
        <ConfigProvider prefixCls={prefix}>
          <div className="App">
            <h1>
              <Space>
                Change Theme:
                {/* radio动态修改prefix */}
                <Radio.Group onChange={handlePrefixChange} value={prefix}>
                  <Radio value="ant">Ant Style</Radio>
                  <Radio value="custom">Custom Style</Radio>
                </Radio.Group>
              </Space>
            </h1>
    
            <h1>antd version: {version}</h1>
            <DatePicker />
            <Button type="primary" style={{ marginLeft: 8 }}>
              Primary Button
            </Button>
          </div>
        </ConfigProvider>
      );
    };
    
    ReactDOM.render(<TestComponent />, document.getElementById("root"));
    
    

最终效果

 

 

 

 

 

最终效果

从上图我们可以看到,radio单选框选择ant style时,此时页面渲染主题色为ant默认的蓝色,而radio选择custom style后,页面渲染的主题色已经动态切换成我们修改后的红色。通过浏览器调试窗口,我们可以发现,按钮的class类名前缀为ant,选择custom style后,class类名前缀切换为custom

 默认样式

 修改后的样式

 

 

 

 

 

写在最后

自此我们动态切换主题的效果就大功告成。

参考链接:
https://blog.csdn.net/m0_58016522/article/details/121751043
https://ant-design.gitee.io/changelog-cn
https://ant-design.gitee.io/docs/react/customize-theme-variable-cn

posted @ 2022-08-31 11:32  艺术诗人  阅读(912)  评论(0编辑  收藏  举报