• react+antd 使用脚手架动态修改主题色


    最近做了一个需求,后台管理系统添加一个可以动态修改ant-design主题色。查询了大多数的文章,发现基本都是抄来抄去,而且文章记录的也一点也不详细。刚刚把这个功能做完了,顺便记录一下如何去修改主题色。主要使用到的包是antd-theme-generator。使用起来非常方便,而且在热更新时,不会出现 js 内存爆栈现象。

    主题思想:主要使用 antd 的 less 变量,修改全局的 less 变量,完成样式的更新。以下是 less 等版本信息。

    案例网址: https://azhengpersonalblog.top/react-ant-admin/

    项目截图

    {
      "antd": "^4.15.5",
      "antd-theme-generator": "^1.2.5",
      "babel-plugin-import": "^1.13.3",
      "less": "^4.1.1",
      "less-loader": "^5.0.0",
      "style-resources-loader": "^1.4.1"
    }
    
    • 1. 首先使用create-react-app脚手架来创建一个项目ant-theme
    D:>npx create-react-app ant-theme
    
    • 2. 使用npm run eject弹射出webpack等配置文件
    D:ant-theme>npm run eject
    
    • 3. 安装antd-theme-generator依赖
    D:ant-theme>cnpm i antd-theme-generator -D
    或者
    D:ant-theme>npm i antd-theme-generator -D
    
    • 4. 在根目录下新建文件color.js,代码如下所示
    const { generateTheme } = require("antd-theme-generator");
    const path = require("path");
    
    const options = {
      antDir: path.join(__dirname, "./node_modules/antd"),
      stylesDir: path.join(__dirname, "./src"), // all files with .less extension will be processed
      varFile: path.join(__dirname, "./src/assets/theme/var.less"), // default path is Ant Design default.less file
      themeVariables: [
        "@primary-color",
        "@link-color",
        "@success-color",
        "@warning-color",
        "@error-color",
        "@layout-text",
        "@layout-background",
        "@heading-color",
        "@text-color",
        "@text-color-secondary",
        "@disabled-color",
        "@border-color-base",
      ],
      outputFilePath: path.join(__dirname, "./public/color.less"),
    };
    
    generateTheme(options)
      .then((less) => {
        console.log("Theme generated successfully");
      })
      .catch((error) => {
        console.log("Error", error);
      });
    
    • 5. 修改public/index.html,代码如下:
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <meta name="theme-color" content="#000000" />
        <meta
          name="description"
          content="Web site created using create-react-app"
        />
        <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    
        <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    
        <title>React App</title>
      </head>
      <!-- 在body下插入此段代码,配合使用window.less.modifyVars -->
      <body>
        <link
          rel="stylesheet/less"
          type="text/css"
          href="%PUBLIC_URL%/color.less"
        />
        <script>
          window.less = { async: false, env: "production" };
        </script>
        <script
          type="text/javascript"
          src="https://cdn.bootcss.com/less.js/2.7.3/less.min.js"
        ></script>
        <noscript>You need to enable JavaScript to run this app.</noscript>
        <div id="root"></div>
      </body>
    </html>
    
    • 6. 修改config/webpack.config.js文件,新增rules项打包 less
    const path = require("path")
    //...............
    // 找到css正则匹配 新增less匹配
    const cssRegex = /.css$/;
    const cssModuleRegex = /.module.css$/;
    const lessRegex = /.(less)$/;
    const lessModuleRegex = /.module.(less)$/;
    //...............
    
    module.exports = function (webpackEnv) {
      return {
        //............
        module: {
          rules: [
            // .........
            {
              oneOf: [
                // .........
                {
                  test: cssRegex,
                  exclude: cssModuleRegex,
                  use: getStyleLoaders({
                    importLoaders: 1,
                    sourceMap: isEnvProduction
                      ? shouldUseSourceMap
                      : isEnvDevelopment,
                  }),
                  sideEffects: true,
                },
                {
                  test: cssModuleRegex,
                  use: [
                    ...getStyleLoaders({
                      importLoaders: 1,
                      sourceMap: isEnvProduction
                        ? shouldUseSourceMap
                        : isEnvDevelopment,
                      modules: {
                        getLocalIdent: getCSSModuleLocalIdent,
                      },
                    }),
                  ],
                },
                // less 文件匹配
                {
                  test: lessRegex,
                  exclude: lessModuleRegex,
                  use: [
                    {
                      loader: "css-loader",
                    },
                    {
                      loader: "less-loader",
                      options: {
                        javascriptEnabled: true,
                      },
                    },
                    //全局引入公共的less 文件 需要安装 style-resources-loader 包
                    {
                      loader: "style-resources-loader",
                      options: {
                        patterns: path.resolve(
                          paths.appSrc,
                          "assets/theme/var.less"
                      },
                    },
                  ],
                  sideEffects: true,
                },
                {
                  test: lessModuleRegex,
                  use: [
                    {
                      loader: "css-loader",
                    },
                    {
                      loader: "less-loader",
                      options: {
                        javascriptEnabled: true,
                      },
                    },
                  ],
                },
              ],
            },
          ],
        },
      };
    };
    
    • 7. 新增src/assets/theme/var.less文件,在里面定义 less 全局变量达到控制主题色。
    @primary-color: rgb(24, 144, 255); // 全局主色
    @link-color: rgb(24, 144, 255); // 链接色
    @success-color: rgb(82, 196, 26); // 成功色
    @warning-color: rgb(250, 173, 20); // 警告色
    @error-color: rgb(245, 34, 45); // 错误色
    @layout-text: rgb(241, 240, 240); // 布局字体色
    @layout-background: rgba(0, 0, 0, 0.85); // 布局背景色
    @heading-color: rgba(0, 0, 0, 0.85); // 标题色
    @text-color: rgba(0, 0, 0, 0.65); // 主文本色
    @text-color-secondary: rgba(0, 0, 0, 0.45); // 次文本色
    @disabled-color: rgba(0, 0, 0, 0.25); // 失效色
    @border-color-base: #d9d9d9; // 边框色
    
    • 8. 修改package.json文件的启动脚本。
    {
      "scripts": {
        "start": "node color && node scripts/start.js",
        "build": "node color && node scripts/build.js"
      }
    }
    
    • 9. 使用 npm 脚本运行项目
    D:ant-theme>npm run start
    

    运行成功打开浏览器输入 http://localhost:3000/ 即可。

    打开控制台,控制台输入以下代码检查是否修改生效!

    window.less.modifyVars({
      "@primary-color": "red",
    });
    

    如图,导入的 antd 的 button 组件背景色变成了红色。自定义的 less 文件引用的@primary-color也变成了红色!

    修改less变量

    现在可以在 react 组件里使用window.less.modifyVars方法来修改主题变量色了!

    • 如何在组件里的 less 文件使用 less 变量。

      还记得开始配置config/webpack.config.js文件吗?在 less 正则匹配的 loader 里往后添加一个style-resources-loader配置即可

    style-resources-loader

    使用注意

    如果在启动项目后,在去动态修改src/assets/theme/var.less里的全局 less 变量或者在组件 less 文件中修改或者引入 less 全局变量,会出现热更新不生效,还需重启项目才能发生变化。

    在打包模式里影响不大!

  • 相关阅读:
    【noip2012】开车旅行
    【AC自动机】专题总结
    【noi2013】【bz3244】树的计数
    BZOJ1069: [SCOI2007]最大土地面积
    BZOJ1185: [HNOI2007]最小矩形覆盖
    BZOJ1047: [HAOI2007]理想的正方形
    BZOJ1801: [Ahoi2009]chess 中国象棋
    BZOJ1925: [Sdoi2010]地精部落
    BZOJ1057: [ZJOI2007]棋盘制作
    BZOJ1217: [HNOI2003]消防局的设立
  • 原文地址:https://www.cnblogs.com/kongyijilafumi/p/14782442.html
Copyright © 2020-2023  润新知